标签:
题意:至少要多少大的子矩阵 能够覆盖全图
比如例子 能够用一个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; }
POJ 2185 Milking Grid KMP循环节周期
标签:
原文地址:http://www.cnblogs.com/gcczhongduan/p/5099937.html