KMP算法——South Central USA 2006 蓝色牛仔裤
来源:互联网 发布:java中如何导人gson 编辑:程序博客网 时间:2024/03/29 16:22
nkoj 1479
Description
IBM和“国家地理”杂志共同研究的一个名为“蓝色牛仔裤”的项目,就是分析成千上万个捐赠的DNA,以便找出世界的人口是怎样构成和分布的。
作为IBM的一名研究员,你的任务就是写一个程序来研究不同DNA片段间的联系。
一个DNA序列由A、T、G、C四个字母来表示,比如“TAGACC”是一种长度为6的DNA序列。
告诉你若干条DNA序列,请找出最长的一段连续DNA序列,该序列出现在了给出的所有DNA序列中(注:也就是求最长公共子串)。
Input
第一行,一个整数n,表示下面有n组测试数据n<=20
对于每组测试数据:
第一行,一个整数m (2 <= m <= 10),表示告诉你了m条DNA序列。
接下来m行,每行表示一条DNA序列,每行的长度不超过60
Output
对于每组测试数据,输出它的最长公共子串。
如果子串的长度小于3,输出"no significant commonalities"
如果有多条长度相等的最长子串,输出字典序最小的那条。
Sample Input
32GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATAGATACTAGATACTAGATACTAGATACTAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAAGATACCAGATACCAGATACCAGATACCAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA3CATCATCATCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCACATCATCATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACATCATCATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
Sample Output
no significant commonalitiesAGATACCATCATCAT
分析:
主要问题是找出n个字符串的最长公共子串,由于数据规模较小,暴力即可:
找出最短的字符串,枚举其所有子串,检查是否也是其他字符串的子串。长度由大到小枚举,第一个满足题意的长度中选择字典序最小的输出即可。
检查子串用KMP算法实现
代码如下:
#include<iostream>#include<cstring>using namespace std;int n,f[70]; //f为kmp算法中的回退表 string s[15];void get_fail(int x){ //预处理s[x]的回退表 int i,j=-1,len=s[x].length();memset(f,0,sizeof(f));f[0]=j=-1; //注意i,j,f[0]的初值 for(i=1;i<len;i++){while(j>=0&&s[x][i]!=s[x][j+1])j=f[j] ;if(s[x][j+1]==s[x][i])j++;f[i]=j;}}bool check(int begin,int len,int x,int y){ //检查s[x] begin开始,长度为len的子串是否为 y的子串 int i,j=-1,l=s[y].length(); //注意j=-1 ,i=0; for(i=0;i<l;i++){ while(j>=0&&s[x][begin+j+1]!=s[y][i])j=f[j];if(s[x][begin+j+1]==s[y][i])j++;if(j==len-1)return true; //找到了 }return false;}void solve(int x){int len=s[x].length(),i,j,k;int find_sub=0;string ans;get_fail(x); for(i=len;i>=3;i--){ //枚举子串的长度 for(j=0;j<=len-i;j++){ //枚举子串的起点 bool ok=true;for(k=1;k<=n;k++) //依次检查各个字符串 if(k!=x&&!check(j,i,x,k)){ ok=false;break;}if(ok){ //找到字典序最小的; find_sub++;if(find_sub==1)ans=s[x].substr(j,i);else ans=min(ans,s[x].substr(j,i));}}if(find_sub){cout<<ans<<endl;return;}}cout<<"no significant commonalities"<<endl;}int main(){ios_base::sync_with_stdio(false);int i,t,l;cin>>t;while(t--){int minn=2e9,x;cin>>n;for(i=1;i<=n;i++) { //找出最短的字符串 cin>>s[i];l=s[i].length();if(l<minn)minn=l,x=i;}solve(x); }}
0 0
- KMP算法——South Central USA 2006 蓝色牛仔裤
- Eight(South Central USA 1998)
- Eight(South Central USA 1998)(八数码)
- BNU All Your Base (Regionals 2011, North America - South Central USA) - from lanshui_Yang
- 算法——KMP
- KMP算法—转
- 算法导论—KMP
- UVALive 6100 Jugglefest Mid-Central USA 2012 模拟
- USA
- KMP 算法——C
- 数据结构——KMP算法
- nyoj5——KMP算法
- 数据结构——KMP算法
- 字符串匹配—KMP算法
- South——完美替代django比较鸡肋的syncdb
- 字符串算法——KMP算法
- 字符串匹配算法——KMP算法
- 算法整理——KMP算法
- 获取手机网络连接状态
- 初级排序算法之冒泡、选择、插入、希尔排序(附Java实现和分析)
- C语言之二重指针
- 应用VMWare配置CentOS虚拟机IP地址
- vs-mda-remote cordova真机测试ios
- KMP算法——South Central USA 2006 蓝色牛仔裤
- 如何判断用户输入的是否为合理手机号
- 一些分享,coding的,songtaste的!
- 贝塞尔曲线
- linux中memset的正确用法
- Okhttp封装、网络层扩展
- START WITH--CONNECT BY PRIO
- 引入tomcat library却没有部署到tomcat上报错
- PAT (Advanced Level) Practise 1102 Invert a Binary Tree (25)