首页 > 代码库 > POJ 2185 Milking Grid KMP循环节周期
POJ 2185 Milking Grid KMP循环节周期
题目来源:POJ 2185 Milking Grid
题意:至少要多少大的子矩阵 可以覆盖全图
例如样例 可以用一个AB 组成一个
ABABAB
ABABAB 可以多出来
思路:每一行求出周期 总共n个 求这n个周期的最小公倍数 如果大于m 取m
每一列求出周期 总共m个求这个m个周期的最小公倍数 如果大于n取n
答案就是2个最小公倍数的积
#include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> using namespace std; const int maxn = 10010; char a[maxn][77]; char b[77][maxn]; int f[maxn][77]; int f2[77][maxn]; int gcd(int a, int b) { return b?gcd(b, a%b):a; } void getFail(char* p, int* f) { int m = strlen(p); f[0] = f[1] = 0; for(int i = 1; i < m; i++) { int j = f[i]; while(j && p[i] != p[j]) j = f[j]; f[i+1] = p[i] == p[j] ? j+1 : 0; } } int main() { int n, m; scanf("%d %d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%s", a[i]); getFail(a[i], f[i]); } for(int i = 0; i < m; i++) { for(int j = 1; j <= n; j++) { b[i+1][j-1] = a[j][i]; } b[i+1][n] = 0; } for(int i = 1; i <= m; i++) getFail(b[i], f2[i]); int ans1 = 1, ans2 = 1; for(int i = 1; i <= n; i++) { ans1 = ans1/gcd(ans1, m-f[i][m])*(m-f[i][m]); if(ans1 > m) { ans1 = m; break; } } for(int i = 1; i <= m; i++) { ans2 = ans2/gcd(ans2, n-f2[i][n])*(n-f2[i][n]); if(ans2 > n) { ans2 = n; break; } } printf("%d\n", ans1*ans2); return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。