Bazinga
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 214 Accepted Submission(s): 89
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个字符串,找出最大的i,使得存在j 满足j<i 且Sj不是Si的字串。
【解题思路】:
看着是个水题本想直接上,看到一片TLE吓得上了个KMP的板。。。
交了一发还是TLE,已经不想做了。。
在某blog的指点下,先判断相邻两个串是否存在字串关系,若Si是Sj的字串,则i和j只需要kmp()一次即可~
减少kmp()次数后800ms过了,,感觉还是不够优美
搜了一下发现有各种做法,Hash、dp......
有空再改,挖坑待填~~
(代码写得丑==)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<string> 6 #include<algorithm> 7 #define eps 1e-8 8 #define zero(x)(((x)>0?(x):-(x))<eps) 9 #define PI acos(-1.0) 10 #define LL long long 11 #define maxn 2200 12 #define IN freopen("in.txt","r",stdin); 13 using namespace std; 14 15 char Str[550][2200]; 16 /*KMP--字符串匹配--单一模版串*/ 17 //char str[maxn],p[maxn];/*p is template string*/ 18 int f[maxn],cnt;//when failed,get to f[i]; 19 void getf(char *p) 20 { 21 memset(f,0,sizeof(f)); 22 int len=strlen(p); /* only cal once, or TLE */ 23 for(int i=1;i<len;i++) 24 { 25 int j=f[i]; 26 while(j&&p[i]!=p[j]) j=f[j]; 27 f[i+1]=(p[i]==p[j]? j+1:0); 28 } 29 } 30 int kmp(char *str,char *p) /*O(len1+len2)*/ 31 { 32 getf(p); 33 cnt=0; 34 int len1=strlen(str),len2=strlen(p); /* only cal once, or TLE*/ 35 for(int i=0,j=0;i<len1;i++) 36 { 37 while(j&&str[i]!=p[j]) j=f[j]; 38 if(str[i]==p[j]) j++; 39 if(j==len2) cnt++;/*Match success*/ 40 if(cnt!=0) break; 41 } 42 return cnt; 43 } 44 45 int main(int argc, char const *argv[]) 46 { 47 //IN; 48 49 int t,ca=1;scanf("%d",&t); 50 while(t--) 51 { 52 int n;scanf("%d",&n); 53 for(int i=1;i<=n;i++) scanf("%s",Str[i]); 54 55 int flag[maxn]={0}; 56 for(int i=1;i<n;i++) 57 if(kmp(Str[i+1],Str[i])!=0) flag[i]=1; 58 59 for(int i=n;i>=1;i--){ 60 for(int j=1;j<i;j++){ 61 if(flag[j]) continue; 62 kmp(Str[i],Str[j]); 63 if(cnt==0){ 64 printf("Case #%d: %d ",ca++,i);goto s; 65 } 66 } 67 } 68 69 printf("Case #%d: -1 ",ca++); 70 s:continue; 71 } 72 73 return 0; 74 }