HDU 5510 Bazinga(KMP)

来源:互联网 发布:北京电脑数据恢复公司 编辑:程序博客网 时间:2024/05/21 05:45

Bazinga

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


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
45ababczabcabcdzabcd4youlovinyouaboutlovinyouallaboutlovinyou5dedefabcdabcdeabcdef3abaccc
 

Sample Output
Case #1: 4Case #2: -1Case #3: 4Case #4: 3

题意:有n个字符串S1,S2...Sn,要求找到最大的Si使得存在Sj不出现在Si中;

字符串匹配典型题,所以毫无疑问KMP(鉴于我还没有完全弄懂KMP是啥,所以直接在网上搜了个板子套上去了)

KMP的时间复杂度是O(n+m),结合题目的数据量,50个样例,500个字符串,每个字符串不超过2000,4000*500^2*50=5*10^8,直接KMP的话会TLE,因此在比较时对比较过程做一个优化;

对于一个字符串S1,如果它相匹配的字符串S2和另一个字符串S3做比较时,S3在遍历时已经毋须再与S1进行比较;因为如果S3与S2匹配,那么与S1肯定匹配;如果S3与S1不匹配,那刚好我们就可以认为3是我们暂时的答案;(因为这里的匹配是一种包含关系,S2包含S1,那么就相当于S3比较时也在和S2中包含的S1部分比较,以及S2的S2部分(即S2本身)比较)

其实我也不知道能优化到什么程度,反正不用每次都比较应该会省时~

然后一定要用scanf……不然会还是会TLE= =

可以在二重循环外输入,也可以在二重循环内中用i直接输入(这个还要快50ms);

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N1=505;const int N2=2005;int f[N2];  char str[N1][N2];//string str[N];int vis[N1];void getfill(string s)  {      memset(f,0,sizeof(f));  //根据其前一个字母得到      for(int i=1;i<s.size();i++)      {          int j=f[i];          while(j && s[i]!=s[j])              j=f[j];          f[i+1]=(s[i]==s[j])?j+1:0;      }  }  int find(string a,string s)  {      int ans=0;      getfill(s);int j=0;      for(int i=0;i<a.size();i++)      {          while(j && a[i]!=s[j])              j=f[j];          if(a[i]==s[j])              j++;          if(j==s.size()){              ans++;          }      }      return ans;  }  int main(){int t,cas=1;scanf("%d",&t);while(t--){int n;scanf("%d",&n);int ans=-1;memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++) scanf("%s",str[i]);for(int i=1;i<=n;i++){for(int j=1;j<=i-1;j++){if(vis[j]) continue;if(find(str[i],str[j])){vis[j]=1;}else ans=i;}}printf("Case #%d: %d\n",cas++,ans);}}/*45ababczabcabcdzabcd4youlovinyouaboutlovinyouallaboutlovinyou5dedefabcdabcdeabcdef3abaccc*/

接下来就是要弄懂KMP究竟是啥了~板子很好用啊~



0 0
原创粉丝点击