HDU5340 Three Palindromes

Three Palindromes

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1680    Accepted Submission(s): 596

http://acm.hdu.edu.cn/showproblem.php?pid=5340php

Problem Description

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

 

Input

First line contains a single integer T20 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

題目大意:

【題目描述】
判斷是否能將字符串S分紅三段 非空迴文串。
【輸入說明】
第一行一個整數T,表示數據組數。
對於每個組,僅包含一個由小寫字母組成的串。
【輸出說明】
對於每一組,單行輸出"Yes" 或 "No「
 
 
對每組數據跑一邊Manacher是爲了求最大半徑數組rad[]
因爲題目要求分紅三部分,因此須要兩個斷點,分紅第1、2、三三個部分
預處理出1、三爲迴文串的狀況,也就是記錄下迴文前綴和迴文後綴的位置,方便直接調用
枚舉上一步找到的兩個斷點,肯定下目前須要討論的第二區間,其中點對應的半徑*2-1若是>=區間長度,則說明符合條件,break掉
 
#include<iostream>//把註釋去掉,上面的加註釋將是另外一種表示方法 
#include<cstdio>
#include<cstring>
using namespace std;
int Case,rad[20010*3],q1[20010*3],q2[20010*3];
char s[20010],c[20010*3];
void manacher(){
    int len=strlen(s+1);
    for(int i=len;i>=0;i--){
        c[i*2]=s[i];
        c[i*2+1]='#';
    }c[0]='$';
    int k=0;
    for(int i=1;i<=len*2;i++){
        if(rad[k]+k>i)rad[i]=min(k+rad[k]-i,rad[2*k-i]);
        else rad[i]=1;
        while(c[i-rad[i]]==c[i+rad[i]])rad[i]++;
        if(i+rad[i]>k+rad[k])k=i;
    }
}
int main(){
    scanf("%d",&Case);
    while(Case--){
        int l=0,r=0;
        memset(rad,0,sizeof(rad));
        memset(q1,0,sizeof(q1));
        memset(q2,0,sizeof(q2));
        scanf("%s",s+1);
        int n=strlen(s+1);n=n*2+1;
        manacher();
        for(int i=1;i<=n;i++){
            if(i==rad[i]&&i!=1)q1[++l]=i;
            if(n+1-i==rad[i]&&i!=n)q2[++r]=i;
            /*if(i==rad[i]&&i!=1)q1[++l]=rad[i];
            if(n+1-i==rad[i]&&i!=n)q2[++r]=rad[i];*/
        }
        bool flag=0;int t1,t2;
        for(int i=1;i<=l;i++){
            if(flag==1)break;
            for(int j=1;j<=r;j++){
                t1=q1[i]*2;t2=n-2*(n-q2[j])-1;
                /*t1=q1[i]*2;t2=n+1-q2[j]*2;*/
                if(t1>t2)continue;
                if(t2-t1==1)continue;
                int mid=(t1+t2)>>1;
                if(rad[mid]*2-1>=t2-t1+1){flag=1;break;}
            }
        }
        if(flag==1){printf("Yes\n");}
        else printf("No\n");
    }
}
相關文章
相關標籤/搜索