POJ 3080 Blue Jeans——暴力 + kmp

来源:互联网 发布:何为道义 知乎 编辑:程序博客网 时间:2024/06/05 00:25

题意:找n个串都包含的最长连续子串,若子串的长度小于三输出no ,若有多个子串输出字典序最小的

思路:暴力枚举第一个串的全部连续子串(O(n^2)),然后用这个子串和其他字符串进行kmp

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 100;char str[maxn][maxn], temp[maxn], ans[maxn];int T, n, Next[maxn];void makeNext(const char *p, int len) {    int i = 0, j = 0;    Next[i] = j;    for (i = 1; i < len; i++) {        while (j && p[i] != p[j]) j = Next[j - 1];        if (p[i] == p[j]) j++;        Next[i] = j;    }}bool kmp(const char *s, const char *p, int len) {    makeNext(p, len);    for (int i = 0, j = 0; i < 60; i++) {        while (j && s[i] != p[j]) j = Next[j - 1];        if (s[i] == p[j]) j++;        if (j == len) {            return true;        }    }    return false;}int main() {    scanf("%d", &T);    while (T--) {        memset(ans, 0, sizeof(ans));        int len = 0;        scanf("%d", &n);        for (int i = 0; i < n; i++) {            scanf("%s", str[i]);        }        for (int i = 0; i < 60; i++) {            for (int j = i; j < 60; j++) {                int cnt = 0;                for (int k = i; k <= j; k++) {                    temp[cnt++] = str[0][k];                }                temp[cnt] = '\0';                bool ok = true;                for (int k = 1; k < n; k++) {                    if (!kmp(str[k], temp, j - i + 1)) {                        ok = false; break;                    }                }                if (ok) {                    if ((len < j - i + 1) || (len == j - i + 1 && strcmp(ans, temp) > 0)) {                        len = j - i + 1;                        strcpy(ans, temp);                    }                }            }        }        if (len < 3) {            printf("no significant commonalities\n");        }        else {            printf("%s\n", ans);        }    }    return 0;}


原创粉丝点击