您的位置:首页 > 其它

HDU Three Palindromes(三部分独立回文)

2015-08-13 20:18 295 查看


Three Palindromes

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1273 Accepted Submission(s): 424



Problem Description

Can we divided a given string S into three nonempty palindromes?



Input

First line contains a single integer T≤20 which
denotes the number of test cases.

For each test case , there is an single line contains a string S which only consist of lowercase English letters.1≤|s|≤20000



Output

For each case, output the "Yes" or "No" in a single line.



Sample Input

2
abc
abaadada




Sample Output

Yes
No
给定一字符串 ,判定是否可以分为连续的三部分,每一部分是个回文串Manacher算法求出各点距右端最大的回文长度,在第一和第三部分满足回文的条件下,看第二部分是否满足
#include <cstdio>
#include <algorithm>
#include <stdlib.h>
#include <cstring>
#include <iostream>
#include <cmath>
#define maxn 20010
using namespace std;
char a[maxn];
char tmp[maxn*2];
int Len[maxn*2];
int one[maxn*2];
int three[maxn*2];
int init(char s[])
{
    tmp[0]='$';
    int len = strlen(s);
    for(int i=1; i<=2*len; i+=2)
    {
        tmp[i] = '#';
        tmp[i+1] = s[i/2];
    }
    tmp[2*len+1] ='#';
    tmp[2*len+2] = '@';
    return 2*len+1;
}
void Manacher(char s[],int len)
{
    int mx=0;
    int po=0;
    for( int i=1; i<=len; i++)
    {
        if(mx > i)
            Len[i] = min(mx-i , Len[2*po-i]);
        else
            Len[i] = 1;
        while( s[i-Len[i]]== s[i+Len[i]] )
        {
            Len[i]++;
        }
        if(Len[i]+i>mx)
        {
            po=i;
            mx=Len[i]+i;
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",a);
        int len = init(a);
        Manacher(tmp,len);
        int k1=0;
        int k2=0;
        for(int i=2; i<len; i++)
        {
            if(Len[i]==i)
                one[k1++]=Len[i];    
            if(len==Len[i]+i-1)
            three[k2++]=Len[i];
        }
         bool flag=false;
         for(int i=0;i<k1;i++)
         {
             for(int j=0;j<k2;j++)
             {
                 int t1 = 2*one[i];    //第二段起点
                 int t2 = len-2*three[j]+1; //第二段终点
                 if(t1>t2) continue;
                 int r = (t1+t2)/2;     
                 if(Len[r]==1) continue;
                 if(Len[r]*2-1 >= t2-t1+1)  //第二段的回文长度>=除去第一段和第三段的长度
                 {
                     flag=true;
                     break;
                 }
             }
             if(flag)
               break;
         }
        if(flag)
            printf("Yes\n");
        else printf("No\n");

    }
    return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: