Bazinga
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3268 Accepted Submission(s): 1049
Problem Description
Ladies and gentlemen, please sit up straight.
Don’t tilt your head. I’m serious.
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.
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
Source
2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)
题意:
n个字符串,找到最大序号的字符串,满足存在比其序号小的字符串不是其子串
思路:
正常的KMP肯定T
所以我们要优化一下
不难发现,我们在判断字符串的时候,可以去除一下没必要重复判断的字符串,这样可以大量节约时间,如果s1.s2.s5是s6的子串,那么,s7只需要判断s6是否为其子串可以间接判断s1,s2,s5,所以用一个数组标记一下需要判断的序号即可
另外,strstr可以完美替代KMP在此题的作用
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<algorithm>
using namespace std;
char s[510][2010];
char s1[510][2010];
int main() {
int T;
int n;
int cas = 1;
scanf("%d", &T);
while (T--) {
memset(s1, 0, sizeof(s1));
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%s", s[i]);
}
int tmp = -1;
int o = 1;
strcpy(s1[1], s[1]);
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= o; j++) {
if (strstr(s[i], s1[j]) == NULL) {
tmp = i;
strcpy(s1[++o], s[i]);
break;
}
}
if (tmp != i) {
strcpy(s1[1], s[i]);
o = 1;
}
}
printf("Case #%d: %d\n", cas++, tmp);
}
return 0;
}