HDU 5510 Bazinga (2015沈阳现场赛,子串判断)

Bazinga

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


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 (1in) such that there exists an integer j (1j<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 (1t50) which is the number of test cases.
For each test case, the first line is the positive integer n (1n500) 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
 
 
【题意】:
n个字符串,找出最大的i,使得存在j 满足j<i 且Sj不是Si的字串。
 
【解题思路】:
看着是个水题本想直接上,看到一片TLE吓得上了个KMP的板。。。
交了一发还是TLE,已经不想做了。。
在某blog的指点下,先判断相邻两个串是否存在字串关系,若Si是Sj的字串,则i和j只需要kmp()一次即可~
减少kmp()次数后800ms过了,,感觉还是不够优美
搜了一下发现有各种做法,Hash、dp......
有空再改,挖坑待填~~
 
(代码写得丑==)
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<string>
 6 #include<algorithm>
 7 #define eps 1e-8
 8 #define zero(x)(((x)>0?(x):-(x))<eps)
 9 #define PI acos(-1.0)
10 #define LL long long
11 #define maxn 2200
12 #define IN freopen("in.txt","r",stdin);
13 using namespace std;
14 
15 char Str[550][2200];
16 /*KMP--字符串匹配--单一模版串*/
17 //char str[maxn],p[maxn];/*p is template string*/
18 int f[maxn],cnt;//when failed,get to f[i];
19 void getf(char *p)
20 {
21     memset(f,0,sizeof(f));
22     int len=strlen(p);  /* only cal once, or TLE */
23     for(int i=1;i<len;i++)
24     {
25         int j=f[i];
26         while(j&&p[i]!=p[j]) j=f[j];
27         f[i+1]=(p[i]==p[j]? j+1:0);
28     }
29 }
30 int kmp(char *str,char *p)    /*O(len1+len2)*/
31 {
32     getf(p);
33     cnt=0;
34     int len1=strlen(str),len2=strlen(p);    /* only cal once, or TLE*/
35     for(int i=0,j=0;i<len1;i++)
36     {
37         while(j&&str[i]!=p[j]) j=f[j];
38         if(str[i]==p[j]) j++;
39         if(j==len2) cnt++;/*Match success*/
40         if(cnt!=0) break;
41     }
42     return cnt;
43 }
44 
45 int main(int argc, char const *argv[])
46 {
47     //IN;
48 
49     int t,ca=1;scanf("%d",&t);
50     while(t--)
51     {
52         int n;scanf("%d",&n);
53         for(int i=1;i<=n;i++) scanf("%s",Str[i]);
54 
55         int flag[maxn]={0};
56         for(int i=1;i<n;i++)
57             if(kmp(Str[i+1],Str[i])!=0) flag[i]=1;
58 
59         for(int i=n;i>=1;i--){
60             for(int j=1;j<i;j++){
61                 if(flag[j]) continue;
62                 kmp(Str[i],Str[j]);
63                 if(cnt==0){
64                     printf("Case #%d: %d\n",ca++,i);goto s;
65                 }
66             }
67         }
68 
69         printf("Case #%d: -1\n",ca++);
70         s:continue;
71     }
72 
73     return 0;
74 }

 

 
posted @ 2015-11-01 01:14  Sunshine_tcf  阅读(333)  评论(0编辑  收藏  举报