http://acm.hdu.edu.cn/contests/contest_show.php?cid=645
Problem Description:
Ladies and gentlemen, please sit up straight.
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".
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.
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.
Sample Input:
4
5
ab
abc
zabc
abcd
zabcd
4
you
lovinyou
aboutlovinyou
allaboutlovinyou
5
de
def
abcd
abcde
abcdef
3
a
ba
ccc
Sample Output:
Case #1: 4
Case #2: -1
Case #3: 4
Case #4: 3
题意:给出n个串s,下标i为1~n,找到最大的i,满足存在一个s[j](1 <= j < i)是s[i]的子串(实际上就是找每个串后面的不包含该串的串的最大下标)。
利用KMP算法:可以求出每个串的Next数组,然后用KMP匹配每两个字符串,找到满足条件的最大下标。
#include<stdio.h> #include<string.h> #include<queue> #include<math.h> #include<stdlib.h> #include<algorithm> using namespace std; const int N=1e4+10; const int INF=0x3f3f3f3f; const int MOD=1e9+7; typedef long long LL; char s[510][2010]; int Len[510], Next[510][2010]; ///Len数组保存每个字符串的长度 void Getnext(int x) ///求出每个字符串的Next数组,保存在Next二维数组中 { int i = 0, j = -1; Next[x][0] = -1; while (i <= Len[x]) { if (j == -1 || s[x][j] == s[x][i]) { i++; j++; Next[x][i] = j; } else j = Next[x][j]; } } int main () { int T, k = 0, i, j, x, y, ans, n; scanf("%d", &T); while (T--) { scanf("%d", &n); ans = -1; k++; for (i = 1; i <= n; i++) { scanf("%s", s[i]); Len[i] = strlen(s[i]); Getnext(i); } for (i = 1; i < n; i++) ///这个双重for循环就是要找到子串不是s[i]的字符串的最大下标 { for (j = i+1; j <= n; j++) { x = 0; for (y = 0; y < Len[j]; y++) { while (s[i][x] != s[j][y] && x >= 0) x = Next[i][x]; x++; ///如果两个字符串中的字符相等++ if (x == Len[i]) break; ///当等于长度时,说明s[i]在s[j]中匹配成功,那么s[j]这个字符串不满足条件 } if (x == Len[i]) break; else ans = max(ans, j); ///如果不等于长度,说明匹配不成功,那么s[i]不是s[j]的子串,更新满足条件的最大下标 } } printf("Case #%d: %d ", k, ans); } return 0; }