考虑kmp比较字符串 然后直接暴力的话 O(t∗n2∗2000) 显然会T 考虑S1是S2的子串 Sn与S1~Sn-1比较时 显然如果比较了S2,S1就没必要再比较了 S2是Sn的子串,S1也肯定是,S2不是Sn子串,ans=max(n,ans)
#include<iostream> #include<cstdlib> #include<cstdio> #include<string> #include<vector> #include<deque> #include<queue> #include<algorithm> #include<set> #include<map> #include<stack> #include<ctime> #include <string.h> #include<math.h> using namespace std; #define ll long long #define pii pair<int,int> const int inf=1e9+7; const int N = 2e3+5; int Next[505][N]; char str[505][N]; bool flag[505]; void get_Nextval(char *P, int *next) { int j = 0; int k = -1; next[0] = -1; int slen = strlen(P); while( j < slen ) { if( -1 == k || P[j] == P[k] ) { ++k; ++j; if( P[j] != P[k] ) { next[j] = k; } else { next[j] = next[k]; } } else { k = next[k]; } } } int index_KMP(char *S, char *P,int*next) { int i = 0; int j = 0; while( i < strlen(S) && j < strlen(P) || -1 == j ) { if( -1 == j || S[i] == P[j] ) { ++i; ++j; } else { j = next[j]; //移动的位数 } } if( j == strlen(P) ) //匹配成功 { return i - j + 1; } else return -1; } int slove(int n){ for(int i=1;i<=n;++i){ get_Nextval(str[i],Next[i]); } int ans=-1; fill(flag,flag+n+1,false);//是后面的串的子串? for(int i=2;i<=n;++i){ for(int j=i-1;j>=1;--j){ if(flag[j]){ continue; } if(-1==index_KMP(str[i],str[j],Next[j])){ ans=max(i,ans); break; } else{ flag[j]=true; } } } return ans; } int main(int argc, char *argv[]) { //freopen("/home/lu/Documents/r.txt","r",stdin); int T; scanf("%d",&T); for(int t=1;t<=T;++t){ int n; scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%s",str[i]); } printf("Case #%d: %d\n",t,slove(n)); } return 0; }