题意: 给定m个串,让你找出它们的最长公共子串
思路: 先二分串的长度,枚举该长度的串(可以从第一个串里找),看该长度是否合法,(就是用这个长度的所有串去匹配给定的 第 2 - m 个串 为提高效率,用kmp)然后得到一个最大长度,再在该长度下寻找一个字典序最小的解即可
POJ3450代码(3080类似)
/************************************************************************* > File Name: poj3450.cpp > Author: ALex > Mail: [email protected] > Created Time: 2015年02月02日 星期一 20时14分57秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const double pi = acos(-1); const int inf = 0x3f3f3f3f; const double eps = 1e-15; typedef long long LL; typedef pair <int, int> PLL; const int N = 222; int next[N]; char str[N]; char mat[4010][N]; char p[N]; int m; void get_next () { int len = strlen (str); next[0] = -1; int j = 0, k = -1; while (j < len) { if (k == -1 || str[k] == str[j]) { ++k; ++j; next[j] = k; } else { k = next[k]; } } } bool match_ok (int s) { int i = 0, j = 0; int lens = strlen (mat[s]); int lent = strlen (str); while (i < lens && j < lent) { if (j == -1 || str[j] == mat[s][i]) { ++i; ++j; } else { j = next[j]; } } if (j == lent) { return 1; } return 0; } bool solve (int L) { bool flag = false; int len = strlen (mat[1]); for (int i = 0; i + L - 1 < len; ++i) { for (int j = i; j < i + L; ++j) { str[j - i] = mat[1][j]; } str[L] = '\0'; get_next (); bool tmp = true; for (int j = 2; j <= m; ++j) { if (!match_ok (j)) { tmp = false; break; } } if (tmp) { flag = true; break; } } return flag; } void Binsearch () { int len = strlen (mat[1]); int l = 1, r = len, mid, ans = -1; while (l <= r) { mid = (l + r) >> 1; if (solve (mid)) { ans = mid; l = mid + 1; } else { r = mid - 1; } } if (ans == -1) { printf("IDENTITY LOST\n"); return; } bool flag = false; for (int i = 0; i + ans <= len; ++i) { for (int j = i; j < i + ans; ++j) { str[j - i] = mat[1][j]; } str[ans] = '\0'; get_next (); bool x = true; for (int j = 2; j <= m; ++j) { if (!match_ok (j)) { x = false; break; } } if (x) { if (!flag) { flag = true; strcpy (p, str); } else { if (strcmp (p, str) > 0) { strcpy (p, str); } } } } printf("%s\n", p); } int main () { while (~scanf("%d", &m), m) { for (int i = 1; i <= m; ++i) { scanf("%s", mat[i]); } Binsearch (); } return 0; }
时间: 2024-10-14 12:20:23