Bazinga
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 101 Accepted Submission(s): 41
Don't tilt your head. I'm serious.
![](http://acm.hdu.edu.cn/data/images/C645-1002-1.jpg)
For n given strings S1,S2,⋯,Sn, labelled from 1 to n, you should find the largest i (1≤i≤n) such that there exists an integer j (1≤j<i) and Sj is not a substring of Si.
A substring of a string Si is another string that occurs in Si. For example, ``ruiz" is a substring of ``ruizhang", and ``rzhang" is not a substring of ``ruizhang".
Input
The first line contains an integer t (1≤t≤50) which is the number of test cases.
For each test case, the first line is the positive integer n (1≤n≤500) and in the following n lines list are the strings S1,S2,⋯,Sn.
All strings are given in lower-case letters and strings are no longer than 2000 letters.
Output
For each test case, output the largest label you get. If it does not exist, output −1.
解题:KMP暴力搞,如果A是B的子串,B是C的子串,那么A一定是C的子串。如果B不是C的子串,A有可能是C的子串。
这说明了什么?这说明如果A是B的子串,那么A就没用了,这就是一个除去冗余的数据的过程,接下来就是暴力了。由于题目的要求是它之前的必须是它的子串,所以,只要比较相邻的串即可除去冗余的串
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 2010; 4 int fail[maxn]; 5 void getFail(char str[]) { 6 for(int i = 0,j = fail[0] = -1; str[i]; ++i) { 7 while(j != -1 && str[i] != str[j]) j = fail[j]; 8 fail[i + 1] = ++j; 9 } 10 } 11 bool match(char sa[],char sb[]) { 12 getFail(sa); 13 for(int i = 0,j = 0; sb[i]; ++i) { 14 while(j != -1 && sb[i] != sa[j]) j = fail[j]; 15 if(!sa[++j]) return true; 16 } 17 return false; 18 } 19 char S[501][maxn]; 20 bool invalid[501]; 21 int main() { 22 int kase,n,cs = 1; 23 scanf("%d",&kase); 24 while(kase--) { 25 scanf("%d",&n); 26 memset(invalid,false,sizeof invalid); 27 for(int i = 0; i < n; ++i) { 28 scanf("%s",S[i]); 29 if(i && match(S[i-1],S[i])) 30 invalid[i-1] = true; 31 } 32 int ret = -1; 33 for(int i = n-1; i >= 0 && ret == -1; --i) { 34 for(int j = 0; j < i && ret == -1; ++j) { 35 if(invalid[j]) continue; 36 if(!match(S[j],S[i])) ret = i + 1; 37 } 38 } 39 printf("Case #%d: %d ",cs++,ret); 40 } 41 return 0; 42 }