Bazinga HDU
阿新 • • 發佈:2019-01-08
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".
InputThe 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 2000letters. OutputFor each test case, output the largest label you get. If it does not exist, output −1. Sample Input
Sample Output
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
For each test case, the first line is the positive integer n(1≤n≤500) and in the following n
All strings are given in lower-case letters and strings are no longer than 2000letters. OutputFor 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
Case #1: 4 Case #2: -1 Case #3: 4 Case #4: 3
因為是找最大值所以從後往前找哪個不是他的子串,那麼正常想法就是從第一個開始判斷了,但是那樣複雜度會過高。
所以對字串進行預處理,如果第I個字串和第i+1個匹配, 就把mark【i】置為1.
這樣,對於一個字串,當判斷前面的字串是不是他的子串時,可以先判斷mark[j]是否為1,因為如果為一說明他是(j+1)的子串,就判斷(j+1)與母串關係就好了。
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[505][2005];
int mark[505];
int n[505][2005];
void kmp(int i)
{
n[i][0]=-1;
int k=-1;
int j=0;
int len=strlen(s[i]);
while(j<len)
{
if(k==-1||s[i][j]==s[i][k])
{
k++;
j++;
n[i][j]=k;
}
else k=n[i][k];
}
}
int match(char *a,char *b,int x)
{
int len1=strlen(a),len2=strlen(b);
//kmp(len1);
int flag=0;
for(int i=0,j=0;i<len2;i++)
{
while(j>0&&a[j]!=b[i])j=n[x][j];
if(a[j]==b[i])j++;
if(j==len1){flag++;break;}
}
if(flag)
{
return 1;
}
else return 0;
}
int main()
{
int n;
int t;
cin>>t;
int z=1;
while(t--)
{
scanf("%d",&n);
memset(mark,0,sizeof(mark));
getchar();
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
kmp(i);
}
int ans=0;
for(int i=0;i<n-1;i++)
{
mark[i]=match(s[i],s[i+1],i);
}
int mmax=0;
for(int i=n-1;i>=0;i--)
{
for(int j=0;j<i;j++)
{
if(mark[j]==1)
continue;
else
{
if(!match(s[j],s[i],j))
{
mmax=i+1;
break;
}
}
}
if(mmax!=0)break;
}
printf("Case #%d: ",z++);
if(mmax==0)printf("-1\n");
else printf("%d\n",mmax);
}
return 0;
}