B-Bazinga(2015-ACM-ICPC沈阳站)
题目大意:给N个字符串找出一个一个最靠后的字符串,这个字符串中前面的字符串存在不是他的子串
-------------------------------------------------------------------------
KMP签到题,要求最大的所以从后往前找,暴力,并且相邻的子串做一下标记,如果前一个是后一个子串,再暴力查找的时候就不用考虑前一个串
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> using namespace std; const int N = 505; const int M = 2010; const int mod = 2009; int n[M]; void getnext(char *s2) { int i=0,j=-1,l=strlen(s2); n[0]=-1; while(i<l) { if(j==-1||s2[i]==s2[j]) { i++;j++; if(s2[i]==s2[j]) n[i]=n[j]; else n[i]=j; } else j=n[j]; } } int kmp(char *s,char *s2) { memset(n,0,sizeof(n)); getnext(s2); int i=0,j=0,k=0,len=strlen(s),l=strlen(s2); while(i<len) { if(j==-1||s[i]==s2[j]) i++,j++; else j=n[j]; if(j==l) k++,j=n[j]; } return k; } char s[N][M]; bool v[N],flag; int main() { int t,m,i,j,k=1; scanf("%d",&t); while(t--) { flag=false; memset(v,true,sizeof(v)); scanf("%d",&m); for(i=1;i<=m;i++) scanf("%s",s[i]); printf("Case #%d: ",k++); for(i=2;i<=m;i++) if(kmp(s[i],s[i-1])>0) v[i-1]=false; for(i=m;i>0&&!flag;i--) for(j=1;j<i&&!flag;j++) if(v[j]) if(kmp(s[i],s[j])==0) { printf("%d\n",i); flag=true; } if(!flag) puts("-1"); } return 0; }