Bazinga
Bazinga
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1605 Accepted Submission(s): 506
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个字符串,分别为S1,S2....Sn,让你求出存在最大的i(1 < = i <= n),使得Si与Sj不匹配(1< = j < i),输出这个i即可。
解法:如果直接用对每次i去和前面i-1个字符串匹配,那么复杂度为0(50*500*500*(2000+2000))会超时的。
首先,需要进行对其优化,因为要求的是最大的i,所以,我们可以从最后一个字符串往前面进行匹配。
其次,如果a<b,Sa是Sb的子串的话,我们可以把Sa合并到Sb里面,可以减少字符串的个数。
然后,就可以避免各自最复杂的情况,可以直接求解答案了、
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 struct Str{ 7 char Str[2010]; 8 int Next;//记录下一个字符串的编号 9 int Fa;//记录上一个字符串的编号 10 }ID[555]; 11 int Len; 12 void getNext(char p[],int next[],int Len_t) 13 { 14 int i=0,j=-1; 15 next[0]=-1; 16 while(i<Len_t){ 17 if(j==-1||p[i]==p[j])next[++i]=++j; 18 else j=next[j]; 19 } 20 } 21 int KMPMatch(char s[],char p[]) 22 { 23 int next[200005]; 24 int i=0,j=0,sign=0; 25 int Len_t=strlen(p),Len_S=strlen(s); 26 getNext(p,next,Len_t); 27 while(i<Len_S) 28 { 29 if(j==-1||s[i]==p[j]){i++;j++;} 30 else j=next[j]; 31 if(j==Len_t) return i-Len_t+1; 32 } 33 return -1; /*返回值是子串在主串第一个匹配的起始位置*/ 34 } 35 int main() 36 { 37 int T,i,j,Ans,N,t=1; 38 scanf("%d",&T); 39 while(T--){ 40 scanf("%d",&N);Ans=1; 41 ID[0].Next=1; 42 for(i=1;i<=N;i++){ 43 scanf(" %s",ID[i].Str); 44 ID[i].Next=i+1;ID[i].Fa=i-1; 45 } 46 for(i=2;i<=N;i++){//合并字符串 47 int TMD=ID[i].Fa; 48 if(!TMD)continue; 49 if(KMPMatch(ID[i].Str,ID[TMD].Str)!=-1){ 50 ID[i].Fa=ID[TMD].Fa; 51 ID[ID[TMD].Fa].Next=i; 52 i--; 53 } 54 } 55 printf("Case #%d: ",t++); 56 for(i=N;i>=1&&Ans;i--){//从后面开始匹配 57 for(j=ID[i].Fa;j>0&&Ans;j=ID[j].Fa){//每次查找上一个不是其子串的字符串 58 if(KMPMatch(ID[i].Str,ID[j].Str)==-1){ 59 printf("%d\n",i);Ans=0;break; 60 } 61 } 62 } 63 if(Ans)printf("-1\n"); 64 65 } 66 return 0; 67 }
转载请备注:
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************