Bazinga
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1472 Accepted Submission(s): 459
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解题思路:在写这题时需要用到匹配算法,一般想到节省时间的就是用kmp,但在c++中提供了一个函数 strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。所以用这个函数更为方便。这题需要剪枝否则会超时。剪枝:首先对每对相邻的子串进行判断,如果编号小的字符串是编号大的字符串的子串,那么该编号小的字符串在后续的判断中无需出现了。接着就从最后一个字符串开始扫描判断就OK了。#include<stdio.h> #include<string.h> char s[510][2005]; int num[510]; int main(){ int t,n,i,j,k; k=1; scanf("%d",&t); while(t--){ scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%s",s[i]); }//输入 int v=-1; memset(num,0,sizeof(num)); for(i=1;i<n;i++){ if(strstr(s[i+1],s[i])!=NULL){ num[i]=1; } }//剪枝 for(i=n;i>=2;i--){ for(j=i-1;j>=1;j--){ if(num[j])continue; int l1=strlen(s[i]); int l2=strlen(s[j]); if(l1<l2)continue; if(strstr(s[i],s[j])==NULL){ v=i; break; } } if(v!=-1)break; } printf("Case #%d: %d\n",k++,v); } return 0; }