POJ 3080 Blue Jeans(串)
Posted ventricle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3080 Blue Jeans(串)相关的知识,希望对你有一定的参考价值。
题目网址:http://poj.org/problem?id=3080
思路:
以第一个DNA序列s为参考序列,开始做以下的操作。
1.将一个字母s[i]作为匹配串。(i为当前遍历到的下标)
2.遍历所有序列,看是否是所有序列的公共子串
3.是所有序列的子串的话,再往后增加一个字母,组成一个长度len+1的匹配串(设原先匹配串长度为len),重复步骤2
4.不是所有序列的子串的话,i=len+i;判断len是否大于3,是的话保存子串。len=0;重复步骤1。(为什么 i=len+i呢?因为len+i都是已经匹配到的,则从i+1 到 i+len 的匹配数会分别比当前匹配数小1…len-1 可以自己推一遍为什么)
5.对结果排序,找出最长,若长度相同的情况下,字典序最小的子串
代码:
1 #include <cstdio> 2 #include <string> 3 #include <cstring> 4 #include <vector> 5 #include <iostream> 6 #include <map> 7 #include <algorithm> 8 using namespace std; 9 int n; 10 char s[15][100]; 11 char temp[100]; 12 vector<string>v; 13 map<string,int>mp; 14 bool cmp(string x,string y){ 15 if(x.length()==y.length()){ 16 int i=0; 17 while (x[i]==y[i]) i++; 18 return x[i]<y[i]; 19 } 20 return x.length()>y.length(); 21 } 22 int main(){ 23 int t; 24 scanf("%d",&t); 25 while (t--) { 26 mp.clear(); 27 v.clear(); 28 scanf("%d",&n); 29 for (int i=0; i<n; i++) scanf("%s",s[i]); 30 for (int i=0; i<60; i++) { 31 int ok=1,l=0; 32 string str=""; 33 memset(temp, 0, sizeof(temp)); 34 temp[0]=s[0][i]; 35 while(l+i<60 && ok){ 36 for (int i=1; i<n; i++) { 37 if(strstr(s[i], temp)==NULL){ 38 ok=0; 39 break; 40 } 41 } 42 if(ok){ 43 str+=s[0][i+l]; 44 l++; 45 temp[l]=s[0][i+l]; 46 } 47 } 48 if(mp[str]==0 && str.size()>=3){ 49 v.push_back(str); 50 mp[str]=1; 51 i=l+i; 52 } 53 } 54 sort(v.begin(), v.end(), cmp); 55 if (v.size()>0) cout<<v[0]<<endl; 56 else printf("no significant commonalities\n"); 57 } 58 }
以上是关于POJ 3080 Blue Jeans(串)的主要内容,如果未能解决你的问题,请参考以下文章
Blue Jeans POJ 3080 寻找多个串的最长相同子串