標籤:blog http 2014 io for re
題目來源: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;}