1. 程式人生 > >hdu 5510

hdu 5510

col class sca void cas 字符串 can break n)

題意:給出n個字符串s[1]..s[n],問是否存在一個i使得s[j](1<=j<i)不是s[i]的子串,求最大i

思路:KMP+暴力

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=503;
 4 const int M=2003;
 5 
 6 char s[N][M];
 7 bool vis[N];
 8 int Next[N][M];
 9 int len[N];
10 int n;
11 int ans;
12 
13 void getNext(int x){
14     int j, k;
15 j = 0; k = -1; Next[x][0] = -1; 16 while(j < len[x]) 17 if(k == -1 || s[x][j] == s[x][k]) 18 Next[x][++j] = ++k; 19 else 20 k = Next[x][k]; 21 } 22 23 int hh(int x,int y)//x是子串,y是母串 24 { 25 int i = 0, j = 0; 26 while(i < len[y] && j < len[x])
27 { 28 if(j == -1 || s[y][i] == s[x][j]) 29 { 30 i++; j++; 31 } 32 else 33 j = Next[x][j]; 34 } 35 if(j == len[x]) 36 return i - len[x]; 37 else 38 return -1; 39 } 40 41 void slove(){ 42 memset(vis,0,sizeof(vis));
43 for(int i=1;i<=n;i++){ 44 for(int j=i+1;j<=n;j++)if(!vis[j]){ 45 if(hh(i,j)==-1) { 46 vis[j]=1;ans=max(ans,j); 47 } 48 else break; 49 } 50 } 51 } 52 int main(){ 53 int t; 54 cin>>t; 55 int k=1; 56 while(t--){ 57 scanf("%d",&n); 58 ans=-1; 59 for(int i=1;i<=n;i++){ 60 scanf("%s",s[i]); 61 len[i]=strlen(s[i]); 62 getNext(i); 63 } 64 slove(); 65 printf("Case #%d: %d\n",k++,ans); 66 67 } 68 }

hdu 5510