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 }

 

posted @ 2017-08-07 20:14  ventricle  阅读(136)  评论(0编辑  收藏  举报