hdu 6103(Kirinriki)

题目链接:Kirinriki

题目描述:

找两个不重叠的字符串A,B。 使得dis(A,B)<=m;(dis(A,B)= sum _{i=0}^{n-1} left | A_i-B_{n-1-i} ight |)。求最长的字符串长度。

思路:

官方题解,双指针维护。简单题。枚举对称中心。

在这里我给出我常用的双指针的写法。


int a[N];
int l=0,r=0,val=0;
while(r没有越界) //如果满足条件
{
    if(val+a[r]<=key) // 加上 a[r] 是否满足条件?
    {
        val+=a[r];
        r++;
        更新最大值//满足条件的区间为 [l,r)
    }
    else  //右移
    {
        val-=a[l];
        l++
    }
}

下面是枚举对称轴的写法:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long int LL;
const int INF = 2e9 + 1e8;

const int MOD = 1e9 + 7;
const double eps = 0.0000000001;
void fre()
{
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
}
#define MSET(a, b) memset(a, b, sizeof(a))

const int maxn = 1e5 + 100;
char str[maxn];
int m;
int len, ans;
void nyist(int x,int y)
{
    int dis=0,l=0,r=0;
    while(y+r<len&&x-r>=0)
    {
        if(dis+abs(str[x-r]-str[y+r])<=m)
        {
            dis+=abs(str[x-r]-str[y+r]);
            r++;
            ans=max(ans,r-l);
        }
        else 
        {
            dis-=abs(str[x-l]-str[y+l]);
            l++;
        }
    }
}
int main()
{
    int ncase;
    scanf("%d", &ncase);
    while (ncase--)
    {
        scanf("%d", &m);
        ans = 0;
        scanf("%s", str);
        len = strlen(str);
        for (int i = 0; i < len; i++)
        {
            nyist(i-1,i+1);
            nyist(i,i+1);
        }
        printf("%d
", ans);
    }
    return 0;
}

/**************************************************/
/**             Copyright Notice                 **/
/**  writer: wurong                              **/
/**  school: nyist                               **/
/**  blog  : http://www.cnblogs.com/coded-ream/  **/
/**************************************************/

还有就是和枚举对称轴相反的写法;

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long int LL;
const int INF = 2e9 + 1e8;

const int MOD = 1e9 + 7;
const double eps = 0.0000000001;
void fre()
{
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
}
#define MSET(a, b) memset(a, b, sizeof(a))

const int maxn = 1e5 + 100;
char str[maxn];
int m;
int len, ans;
void nyist(int x,int y)
{
    int dis=0,l=0,r=0;
    while(x+r<y-r)
    {
        if(dis+abs(str[x+r]-str[y-r])<=m)
        {
            dis+=abs(str[x+r]-str[y-r]);
            r++;
            ans=max(ans,r-l);
        }
        else 
        {
            dis-=abs(str[x+l]-str[y-l]);
            l++;
        }
    }
}
int main()
{
    int ncase;
    scanf("%d", &ncase);
    while (ncase--)
    {
        scanf("%d", &m);
        ans = 0;
        scanf("%s", str);
        len = strlen(str);
        len--;
        for(int i=1;i<=len;i++) nyist(0,i);
        for(int i=0;i<len;i++) nyist(i,len);
        printf("%d
", ans);
    }
    return 0;
}

/**************************************************/
/**             Copyright Notice                 **/
/**  writer: wurong                              **/
/**  school: nyist                               **/
/**  blog  : http://www.cnblogs.com/coded-ream/  **/
/**************************************************/
原文地址:https://www.cnblogs.com/coded-ream/p/7343946.html