PKU 1226 Substrings(字符串匹配+暴搜KMP模板)
原题大意:原题链接
给出n个字符串,找出一个最长的串s,使s或者s的反转字符串(只要其中一个符合就行)同时满足是这n个串的子串。
对于样例,第一组ABCD BCDFF BRCD最长的串就是CD;第二组rose orchid最长的子串就是ro
#include<cstdio> #include<cstring> #include<iostream> using namespace std; char str[101][101]; int next[101],rnext[101]; /* void get_next(char *s) { next[1]=0; int i=1,j=0; int slen=strlen(s); while(i<slen){ if(j==0||s[i-1]==s[j-1]){ i++,j++; next[i]=j; } else j=next[j]; } } 在t字符串在s字符串中匹配 bool KMP(char *s,char *t) { int i=0,j=1; int slen=strlen(s),tlen=strlen(s); while(i<=slen&&j<=tlen){ if(j==0||s[i-1]==t[j-1]) i++,j++; else j=next[j]; } if(j>tlen) return true; return false; } */ void get_next(int l,int r,bool flag) { if(flag){ next[l]=l-1; int i=l,j=l-1; while(i<r){ if(j==l-1||str[0][i]==str[0][j]){ i++,j++; next[i]=j; } else j=next[j]; } } else{ rnext[r]=r+1; int i=r,j=r+1; while(i>l){ if(j==r+1||str[0][i]==str[0][j]){ i--,j--; rnext[i]=j; } else j=rnext[j]; } } } //将第一个字符串的l~r位置在第k个字符串中进行匹配 bool KMP(int id,int l,int r,bool flag) { int len=strlen(str[id]); if(flag){ int i=0,j=l; while(i<len&&j<=r){ if(j==l-1||str[id][i]==str[0][j]) i++,j++; else j=next[j]; } if(j>r) return true; } else{ int i=0,j=r; while(i<len&&j>=l){ if(j==r+1||str[id][i]==str[0][j]) i++,j--; else j=rnext[j]; } if(j<l) return true; } return false; } int main() { int T,n; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%s",str[i]); int len=strlen(str[0]),ans=0; for(int i=0;i<len;i++){ for(int j=i;j<len;j++){ int len=j-i+1; get_next(i,j,true); get_next(i,j,false); int cnt=1; for(int k=1;k<n;k++){ if(KMP(k,i,j,true)||KMP(k,i,j,false)) cnt++; else break; } if(cnt==n&&ans<len) ans=len; } } printf("%d\n",ans); } return 0; }