hdu 5510 Bazinga 剪枝+find()/strstr()/KMP

来源:互联网 发布:mac os x 安装软件 编辑:程序博客网 时间:2024/06/06 04:55


Bazinga

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


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
 

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

Recommend
wange2014   |   We have carefully selected several similar problems for you:  5932 5931 5930 5929 5928 
 

Statistic | Submit | Discuss | Note


三个方法不用剪枝似乎都会超时,

剪枝方法:加入a是b的子串,那么考虑c串是否能作为答案时,不用考虑a,只用考虑b。

因为如果b不是c的子串,c已经可以作为答案,自然不用考虑a。如果b是c的子串,那么a自然也是c的子串,并无任何帮助。

1.find()

#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<vector>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)#define mes(a,x,s)  memset(a,x,(s)*sizeof a[0])#define mem(a,x)  memset(a,x,sizeof a)#define ysk(x)  (1<<(x))typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn=500    ;string s[maxn+5];int n,T;bool vis[maxn+10];int main(){    std::ios::sync_with_stdio(false);   int T,kase=0;cin>>T;   while(T--)   {       cin>>n;       for1(i,n)  cin>>s[i];       int ans=-1;       mes(vis,0,n+1);       for(int i=1;i<=n;i++)       {          for1(j,i-1) if(!vis[j])          {              if(s[i].find(s[j])==string::npos)              {                ans=i;                break;              }              else              {                  vis[j]=1;              }          }       }       printf("Case #%d: %d\n",++kase,ans);   }   return 0;}


2.strstr()

#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<vector>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)#define mes(a,x,s)  memset(a,x,(s)*sizeof a[0])#define mem(a,x)  memset(a,x,sizeof a)#define ysk(x)  (1<<(x))typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn=500    ;char s[maxn+5][2010];int n;bool vis[maxn+10];int main(){   int T,kase=0;scanf("%d",&T);   while(T--)   {       scanf("%d",&n);       for1(i,n)  scanf("%s",s[i]);       int ans=-1;       mes(vis,0,n+1);       for(int i=1;i<=n;i++)       {          for1(j,i-1) if(!vis[j])          {              if(!strstr(s[i],s[j]))              {                ans=i;                break;              }              else              {                  vis[j]=1;              }          }       }       printf("Case #%d: %d\n",++kase,ans);   }   return 0;}


3.KMP

#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<vector>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)#define mes(a,x,s)  memset(a,x,(s)*sizeof a[0])#define mem(a,x)  memset(a,x,sizeof a)#define ysk(x)  (1<<(x))typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn=500    ;char s[maxn+5][2010];int n,nex[2010];bool vis[maxn+10];void getnex(char *P){    nex[0]=nex[1]=0;    int len=strlen(P);    for(int i=1;i<len;i++)    {        int j=nex[i];        while(j&&P[j]!=P[i])  j=nex[j];        nex[i+1]= P[j]==P[i]?j+1:0;    }}bool match(char* T,char *P){    int j=0;    int L=strlen(T),len=strlen(P);    for(int i=0;i<L;i++)    {        while(j&&T[i]!=P[j]) j=nex[j];        if(T[i]==P[j])  j++;        if(j==len)  return true;    }    return false;}bool find(char *T,char *P){      getnex(P);      return match(T,P);}int main(){   int T,kase=0;scanf("%d",&T);   while(T--)   {       scanf("%d",&n);       for1(i,n)  scanf("%s",s[i]);       int ans=-1;       mes(vis,0,n+1);       for(int i=1;i<=n;i++)       {          for1(j,i-1) if(!vis[j])          {              if(!find(s[i],s[j]))              {                ans=i;                break;              }              else              {                  vis[j]=1;              }          }       }       printf("Case #%d: %d\n",++kase,ans);   }   return 0;}


0 0
原创粉丝点击