POJ3080 && POJ 3450

来源:互联网 发布:正大数据恢复中心骗局 编辑:程序博客网 时间:2024/06/03 09:17

题意: 给定m个串,让你找出它们的最长公共子串

思路: 先二分串的长度,枚举该长度的串(可以从第一个串里找),看该长度是否合法,(就是用这个长度的所有串去匹配给定的 第 2 - m 个串 为提高效率,用kmp)然后得到一个最大长度,再在该长度下寻找一个字典序最小的解即可


POJ3450代码(3080类似)


/*************************************************************************    > File Name: poj3450.cpp    > Author: ALex    > Mail: zchao1995@gmail.com     > 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;}


1 0
原创粉丝点击