您的位置:首页 > 其它

HDU 5510 Bazinga(模拟双向链表或kmp或AC自动机)

2016-10-07 14:49 411 查看

Bazinga(传送门)

Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other)

Total Submission(s) : 42 Accepted Submission(s) : 19

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

Source

2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)

题意

给n(1≤n≤500)个字符串,求一个最大的i,使得存在一个Sj 不是Si的子串。

解题思路

假设存在一个Si串包含Sj串,那么接下来的字符串中如果有一个字符串Sk包含Si,那么Sk一定包含Sj,所以Sj就没有判断的必要了,可以从判断列表中删除。在此我们可以用两种方法解决此问题:1为自己模拟双向链表,2为用STL解决

此处可以用KMP,AC自动机这些字符串匹配的高效算法解决

代码

/*除去冗长的头文件*/

const double PI = 3.1415926535898;
const double eps = 1e-10;
const int MAXM = 2e3 + 5;
const int MAXN = 1e3 + 5;
const int INF = 0x3f3f3f3f;

int T, n;
char S[MAXM];
string A[MAXN];
int par[MAXN], chi[MAXN];
int st;

void init() {
for(int i = 0; i < MAXN; i ++) {
par[i] = i - 1;
chi[i] = i + 1;
}
st = 0;
}

void del(int x) {
if(x == st) {
st = chi[x];
par[st] = -1;
return;
}
int p = par[x];
int c = chi[x];
par[c] = p;
chi[p] = c;
}

int main() {
#ifndef ONLINE_JUDGE
//FIN;
//FOUT;
#endif
IO_Init();
scanf("%d", &T);
int cas = 1;
while(T --) {
scanf("%d", &n);
init();
for(int i = 0; i < n; i ++) {
scanf("%s", S);
A[i] = string(S);
}
int ans = -1;
for(int i = 1; i < n; i ++) {
for(int j = st; j < i; j = chi[j]) {
if(A[i].find(A[j]) != string::npos) {
del(j);
} else {
ans = i + 1;
}
}
}
printf("Case #%d: %d\n", cas ++, ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: