您的位置:首页 > 其它

2015ACM/ICPC亚洲区沈阳站 HDU

2017-10-14 19:03 381 查看


Bazinga

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 5242    Accepted Submission(s): 1647


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".

 

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.

 

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使得,存在一个在他前面的字符串不是他的子串
暴力 + 剪枝
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <stack>
#include <cmath>
#include <queue>
#include <map>
using namespace std;
#define N 2100
char s

;
char pattern
;
int nest[600]
;
int vis
;
int n,m;
void getnext(int p)
{
// int len=strlen(pattern);
int j=-1;
nest[p][0]=-1;
for(int i=1;pattern[i]!='\0';i++) {
while(j!=-1&&pattern[i]!=pattern[j+1])
j=nest[p][j];
if(pattern[j+1]==pattern[i])
j++;
nest[p][i]=j;
}

}
bool KMP(char s[], char pattern[], int p)
{
int j = -1;
for(int i=0;s[i]!='\0';i++) {
while(j!=-1&&s[i]!=pattern[j+1])
j=nest[p][j];
if(s[i]==pattern[j+1])
j++;
if(pattern[j+1]=='\0')
return true;
}
return false;
}
int main()
{
int T;
int flag = 0;
scanf("%d",&T);
getchar();
for(int m = 1; m <= T; m++) {
memset(vis, 0, sizeof(vis));
int ans = -1;
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%s",s[i]);
strcpy(pattern,s[i]);
getnext(i);
}
for(int i = 0; i < n; i++) {

for(int k = i - 1; k >= 0; k--) {
if(vis[k] == 1)
continue;
if(!KMP(s[i], s[k], k)) { //不是子串还可以用strstr函数
ans = i + 1;
}
else //如果当前是i的子串的话后面的只需要匹配i子串判断不需要k了
vis[k] = 1;
}
}
printf("Case #%d: %d\n", m, ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐