Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 10451 | Accepted: 3598 |
Description
Input
Output
Sample Input
2 3 ABCD BCDFF BRCD 2 rose orchid
Sample Output
2 2
#include<iostream> #include<cstring> #include<string> #include<cstdio> using namespace std; int nextp[105],nexts[105],n; char a[105][105]; char b[105]; //将模式串翻转 int lena0; //模式串的长度 //我的思路是用第一个字符串当模式串,然后再枚举长度由大到小求next匹配 void getnextp(int sta,int len) //模式串 { int i,j; len=sta+len; //相对位置变成绝对位置 nextp[sta]=sta,nextp[sta+1]=sta; for(i=sta+1;i<len;i++) { j=nextp[i]; while(j!=sta&&a[0][i]!=a[0][j]) j=nextp[j]; if(a[0][i]==a[0][j]) nextp[i+1]=j+1; else nextp[i+1]=sta; } } void getnexts(int sta,int len) //翻转后的模式串 { int i,j; sta=lena0-sta-len; //要把子串的位置转换成b的位置 len=sta+len; nexts[sta]=sta,nexts[sta+1]=sta; for(i=sta+1;i<len;i++) { j=nexts[i]; while(j!=sta&&b[i]!=b[j]) j=nexts[j]; if(b[i]==b[j]) nexts[i+1]=j+1; else nexts[i+1]=sta; } } int KMP(int sta,int len) { int i,j,k; int sta1=sta; int sta2=lena0-sta-len; int len1=sta+len; int len2=sta2+len; for(k=1;k<n;k++) //后面的串都和第一个串的子串匹配 { int flag=0; j=sta1; for(i=0;i<strlen(a[k]);i++) { while(j!=sta1&&a[k][i]!=a[0][j]) j=nextp[j]; if(a[k][i]==a[0][j]) j++; if(j==len1) { flag=1; break; } } j=sta2; for(i=0;i<strlen(a[k]);i++) { while(j!=sta2&&a[k][i]!=b[j]) j=nexts[j]; if(a[k][i]==b[j]) j++; if(j==len2) { flag=1; break; } } if(flag==0) //有一个没有匹配,便返回0 return 0; } return 1; } int main() { int i,j,T,l; scanf("%d",&T); while(T--) { scanf("%d",&n); if(n==0) break; for(i=0;i<n;i++) scanf("%s",a[i]); lena0=strlen(a[0]); for(i=0;i<lena0;i++) b[i]=a[0][lena0-i-1]; b[lena0]='\0'; int flag=0; for(i=lena0;i>=1;i--) //从长度lena0开始往下枚举 { int flag1=0; //长度为i的是否存在 for(j=0;j<=lena0-i;j++) //模式串分解的起始位置 { getnextp(j,i); getnexts(j,i); if(KMP(j,i)) { flag1=1; printf("%d\n",i); break; } } if(flag1) { flag=1; break; } } if(flag==0) puts("0"); } return 0; }