HDU 5510 Bazinga

Bazinga

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 101    Accepted Submission(s): 41

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

 解题:KMP暴力搞,如果A是B的子串,B是C的子串,那么A一定是C的子串。如果B不是C的子串,A有可能是C的子串。

这说明了什么?这说明如果A是B的子串,那么A就没用了,这就是一个除去冗余的数据的过程,接下来就是暴力了。由于题目的要求是它之前的必须是它的子串,所以,只要比较相邻的串即可除去冗余的串

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 2010;
 4 int fail[maxn];
 5 void getFail(char str[]) {
 6     for(int i = 0,j = fail[0] = -1; str[i]; ++i) {
 7         while(j != -1 && str[i] != str[j]) j = fail[j];
 8         fail[i + 1] = ++j;
 9     }
10 }
11 bool match(char sa[],char sb[]) {
12     getFail(sa);
13     for(int i = 0,j = 0; sb[i]; ++i) {
14         while(j != -1 && sb[i] != sa[j]) j = fail[j];
15         if(!sa[++j]) return true;
16     }
17     return false;
18 }
19 char S[501][maxn];
20 bool invalid[501];
21 int main() {
22     int kase,n,cs = 1;
23     scanf("%d",&kase);
24     while(kase--) {
25         scanf("%d",&n);
26         memset(invalid,false,sizeof invalid);
27         for(int i = 0; i < n; ++i) {
28             scanf("%s",S[i]);
29             if(i && match(S[i-1],S[i]))
30                 invalid[i-1] = true;
31         }
32         int ret = -1;
33         for(int i = n-1; i >= 0 && ret == -1; --i) {
34             for(int j = 0; j < i && ret == -1; ++j) {
35                 if(invalid[j]) continue;
36                 if(!match(S[j],S[i])) ret = i + 1;
37             }
38         }
39         printf("Case #%d: %d\n",cs++,ret);
40     }
41     return 0;
42 }
View Code

 

转载于:https://www.cnblogs.com/crackpotisback/p/4925990.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值