Description
Input
Output
Sample Input
3
2
GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
3
GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA
GATACTAGATACTAGATACTAGATACTAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA
GATACCAGATACCAGATACCAGATACCAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA
3
CATCATCATCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
ACATCATCATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AACATCATCATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
Sample Output
no significant commonalities
AGATAC
CATCATCAT
题意 给你n个DNA串 求它们的长度最大的公共子串 如果有多个 输出字典序最小的 长度小于3的不算
每个DNA串的长度都是60 可以从子串长度为60依次递减 并枚举所有该长度子串 当某个长度的子串也为其它n-1个串的子串时 就是我们要的答案了
判断是否为其它DNA串的子串直接kmp就行了
#include<cstdio> #include<cstring> using namespace std; const int N = 15, M = 65, L = 60; bool kmp (char s[], char p[]) { int next[M]; next[0] = -1, next[1] = 0; int plen = strlen (p), i = 0, j,slen = strlen (s); while (++i < plen - 1) { j = next[i]; while (j != -1 && p[i] != p[j]) j = next[j]; next[i + 1] = j + 1; } i = j = 0; while (i < slen && j < plen) { if (j == -1 || s[i] == p[j]) ++i, ++j; else j = next[j]; } return j == plen; } int main() { int cas, n, flag; char s[N][M], tans[M],ans[M]; scanf ("%d", &cas); while (cas--) { scanf ("%d", &n); for (int i = flag = 0; i < n; ++i) scanf ("%s", s[i]); for (int lans = L; lans > 2 && flag == 0; --lans) { strcpy(ans,"ZZ"); for (int i = 0, j, k; i + lans <= L; ++i) { for (j = 0; j < lans; ++j) tans[j] = s[0][i + j]; tans[j] = '\0'; for (k = 1; k < n; ++k) if (!kmp (s[k], tans)) break; if (k == n) { if(strcmp(ans,tans)>0) strcpy(ans,tans); flag = 1; } } } if (flag == 1) printf ("%s\n", ans); else printf ("no significant commonalities\n"); } return 0; }
POJ 3080 Blue Jeans(KMP 最长公共子串),布布扣,bubuko.com
POJ 3080 Blue Jeans(KMP 最长公共子串)
原文地址:http://blog.csdn.net/iooden/article/details/38457875