Bazinga
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 593 Accepted Submission(s): 241
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".
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.
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
题意:n个字符串,s[i] (1≤i≤n),找到最大的i,是得存在j(1≤j<i)使得,s[j]不是 s[i]的子串。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char s[550][2200]; int Next[550][2200]; int Judge(int w, int o) { int i = 0 , j = 0; int l1, l2; l1 = strlen(s[w]); l2 = strlen(s[o]); while(i < l1 && j < l2) { if(s[w][i] == s[o][j] || i == -1) { i++; j++; } else i = Next[w][i]; if(i == l1) { return true; } } return false; } void getNext(int q) { int j, k; int i = strlen(s[q]); j = 0; k = -1; Next[q][0] = -1; while(j < i) { if(k == -1 || s[q][j] == s[q][k]) { j++; k++; Next[q][j] = k; } else k = Next[q][k]; } } int main() { int t, n, index, l = 1; scanf("%d", &t); while(t--) { scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%s", s[i]); getNext(i); } index = -1; int q; for(int i = n-2; i >= 0; i--) { if(!Judge(i, i+1)) 找到一个字符串不满足前后是子串关系后,从后向前找最大的不满足子串的串 { q = i; for(int j = n-1; j > q; j--) { if(!Judge(q, j)) index = index > j ? index : j; } } } if(index == -1) printf("Case #%d: %d ", l++, index); else printf("Case #%d: %d ", l++, index+1); } return 0; }
strstr阔以考虑……脉动回来
学长递归写法……
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n, num; char s[550][2200]; void slove(int k) { if(k == 0 || num == n-1) return ; if(strstr(s[k], s[k-1])) slove(k-1); // 向下寻找 else { for(int i = n-1; i >= num; i--) // 找最大的 下标 { if(strstr(s[i], s[k-1]) == 0) { num = i; break; // } } slove(k-1); // 继续向下寻找看是否有 存在 k 使 num 最大 } } int main() { int t, l = 1; scanf("%d", &t); while(t--) { scanf("%d", &n); num = -1; for(int i = 0; i < n; i++) scanf("%s", s[i]); slove(n-1); printf("Case #%d: %d ", l++, num == -1 ? num : num+1); } return 0; }