题目描述
记字符串ww的倒置为w^RwR。例如(abcd)^R=dcba(abcd)R=dcba,(abba)^R=abba(abba)R=abba。
对字符串x,如果xx满足x^R=xxR=x,则称之为回文;例如abba是一个回文,而abed不是。
如果x能够写成的ww^Rww^RwwRwwR形式,则称它是一个“双倍回文”。换句话说,若要xx是双倍回文,它的长度必须是44的倍数,而且xx,xx的前半部分,xx的后半部分都要是回文。例如abbaabbaabbaabba是一个双倍回文,而abaabaabaaba不是,因为它的长度不是4的倍数。
xx的子串是指在xx中连续的一段字符所组成的字符串。例如bebe是abedabed的子串,而acac不是。
xx的回文子串,就是指满足回文性质的xx的子串。
xx的双倍回文子串,就是指满足双倍回文性质的xx的子串。
你的任务是,对于给定的字符串,计算它的最长双倍回文子串的长度。
输入格式
输入分为两行。
第一行为一个整数,表示字符串的长度。
第二行有个连续的小写的英文字符,表示字符串的内容。
输出格式
输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出00。
输入输出样例
输入 #1
16 ggabaabaabaaball
输出 #1
12
说明/提示
N le 500000N≤500000
其实今天考试题是这个(差不多啦)
题解:emm菜鸡如我,附上40分暴力代码就溜。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<bits/stdc++.h> using namespace std; const int N=500010; int n,p[N],ans; int Yao_Chen_Lai_Le; char s[N]; bool pd(int x,int len){ int d=len/2; for(int i=x;i<=x+d-1;i++) if(s[i]!=s[i+d]) return 0; for(int i=x,j=x+d-1;i<=j;i++,j--) if(s[i]!=s[j]) return 0; return 1; } int work(){ scanf("%s",s+1); n=strlen(s+1); int p=(n/4)*4; for(int l=p;l>=4;l-=4) for(int i=1;i+l-1<=n;i++) if(pd(i,l)==1) return l; return 0; } int main(){ freopen("altar.in","r",stdin); freopen("altar.out","w",stdout); scanf("%d",&Yao_Chen_Lai_Le); while(Yao_Chen_Lai_Le--) printf("%d ",work()); return 0; }