nefu 1316 Ela的回文串 manacher

Ela的回文串

Problem:1316

Time Limit:1000ms

Memory Limit:65535K

Description

Ela在算法课上学习了回文串,但是她不想在回文串中出现她不喜欢的字符。
现在Ela告诉我们她喜欢的字符是{A, H, I, M, O, T, U, V, W, X, Y} 
她想知道对于某个字符串中只包含她喜欢的字符的最长回文子串的长度是多少?

Input

第一行是一个整数T,代表测试样例的个数
接下来T行是T个非空字符串(只包含大写字母)

IOIKIOOI
ROQ
WOWMAN

Sample Output

4
1
3

Hint

对于第一组样例答案是:IOOI
对于第二组样例答案是:O
对于第三组样例答案是:WOW

Source

DT2131
 
    
 
    
我用的方法是在计算p数组的值,判断是否构成回文时看那个字符是否是ELA喜欢的字符。比如BAOAB以O为中心时判断到B时就不++,这样计算结果是对的。
但是以不喜欢的字符为 中心的情况还没排除。这种只要在遍历p数组求MAX值时不考虑他即可。
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=223000;
int n,p[maxn];
char s[maxn],str[maxn];
int judge(int i)
{
    if(str[i]=='A'||str[i]=='H'||str[i]=='I'||str[i]=='M'||str[i]=='O'||str[i]=='T'||str[i]=='U'||str[i]=='V'||str[i]=='W'||
          str[i]=='X'||str[i]=='Y'||str[i]=='#')return 1;
        else return 0;
}
void kp()
{
    int i,mx=0;
    int id=0;

    for(i=1;i<n;i++)
    {
        if(mx>i)p[i]=min(p[2*id-i],mx-i);
        else p[i]=1;
        while(str[i+p[i]]==str[i-p[i]]&&judge(i-p[i]))
        p[i]++;
        if(p[i]+i>mx)
        {
            mx=p[i]+i;
            id=i;
        }
    }
}

void init()
{
    int i,k=1;
    str[0]='$';

    for(int i=0;i<=n;i++)
    {
       str[k++]='#';
       str[k++]=s[i];
    }
    str[k++]='#';
    n=k;

}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%s",s);
        n=strlen(s);
        memset(p,0,sizeof(p));
        init();
        kp();
        int max=-999;
        for(int i=0;i<n;i++)
        {
            //printf("%d ",p[i]);
            if(p[i]>max&&judge(i))max=p[i];
        }
        if(max>0)printf("%d\n",max-1);
        else printf("0\n");
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/mayuqing98/article/details/79185043