Bazinga
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 4572 Accepted Submission(s): 1459
Problem Description
Ladies and gentlemen, please sit up straight.
Don't tilt your head. I'm serious.
For n given strings S, 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 S is not a substring of S.
A substring of a string S is another string that occurs in S. 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 S, 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 S is not a substring of S.
A substring of a string S is another string that occurs in S. 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 S.
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 S.
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
题意
找到一个最大的i,使得i前面的字符串至少有一个不是它的子串
分析:如果直接用KMP进行匹配操作就会超时,这里需要剪枝的是如果前面的字符串已经是另一个字符串的子串了
就不需要再把它拿来进行匹配。
就不需要再把它拿来进行匹配。
一开始用的是vector来存需要匹配的字符串,但是这样的话,在存入和取出的时候用时也很高
后面就换 vis来记录不用匹配的下标,就过了
代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int N = 1000002;
int Next[N];
char S[N], T[N];
char str[510][2100];
int slen, tlen;//注意每次一定要计算长度
int len[510];
int vis[510];
vector<int>V;
void getNext(char *T,int tlen)
{
int j, k;
j = 0; k = -1; Next[0] = -1;
while(j < tlen)
if(k == -1 || T[j] == T[k])
Next[++j] = ++k;
else
k = Next[k];
}
/*
返回模式串T在主串S中首次出现的位置
返回的位置是从0开始的。
*/
int KMP_Index(char *S,int slen,char *T,int tlen)
{
int i = 0, j = 0;
getNext(T,tlen);
while(i < slen && j < tlen)
{
if(j == -1 || S[i] == T[j])
{
i++; j++;
}
else
j = Next[j];
}
if(j == tlen)
return i - tlen;
else
return -1;
}
int main()
{
int TT,Case=0;;
int i, cc,n,sum,maxx;
scanf("%d",&TT);
while(TT--)
{
memset(vis,0,sizeof(vis));
maxx=-1;
Case++;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s",str[i]);
len[i]=strlen(str[i]);
}
for(int i=1;i<n;i++)
{
sum=0;
for(int j=0;j<i;j++)
{
if(!vis[j]){
if(KMP_Index(str[i],len[i],str[j],len[j])>=0)
vis[j]=1;
else
{
maxx=i;
break;
}
}
}
}
if(maxx==-1) printf("Case #%d: %d
",Case,maxx);
else printf("Case #%d: %d
",Case,maxx+1);
}
return 0;
}