poj3080~KMP+枚举

来源:互联网 发布:曲面软件 编辑:程序博客网 时间:2024/06/05 09:31

看DISCUSS里面都在说枚举+KMP就可以解决了,原来这么方便。直接从长度60的子串开始枚举,看看是否每个DNA都包含这个子串,思路非常简单。

#include<iostream>#include<string>#include<fstream>using namespace std;int next[65];char DNA[12][65],dna[65],ans[65];void Getnext(char a[],int *next,int n){int i,j;j=-1;i=0;next[0]=-1;while(i<n)if(j==-1||a[i]==a[j]){i++;j++;next[i]=j;}else j=next[j];}int KMP(char S[],char T[],int lenT) //S是主串,T是子串{int i=0,j=0,lenS=60;Getnext(T,next,lenT); while(i<lenS&&j<lenT){if(j==-1||S[i]==T[j]){i++;j++;}else j=next[j];}if(j>=lenT) return 1;else return 0;}int main(){int i,j,x,t,len,k,flag;char temp;cin>>t;while(t--){scanf("%d",&x);for(i=0;i<x;i++)scanf("%s",DNA[i]);flag=1;for(len=60;len>=3&&flag;len--)//从长度60开始枚举,如果枚举中出现答案了就可以退出了{for(j=0;j<len;j++) //构造一个字典序最长的ans字符串,用于接下来的比较ans[j]='Z';ans[len]='\0';for(i=0;i+len<=60;i++)     //枚举开始{for(j=0;j<len;j++)     //这是构建一个子串的过程dna[j]=DNA[0][i+j];dna[len]='\0';k=1;for(j=1;j<x;j++)        //检测是否全都包含这个子串{if( KMP(DNA[j],dna,len) )k++;}if(k==x){flag=0;if(strcmp(dna,ans)<0)  //要输出字典序最小的字符串strcpy(ans,dna);}}}if(flag==0)cout<<ans<<endl;else cout<<"no significant commonalities"<<endl;}}


 

0 0
原创粉丝点击