poj 2185

Milking Grid

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 6609   Accepted: 2794

Description

Every morning when they are milked, the Farmer John's cows form a rectangular grid that is R (1 <= R <= 10,000) rows by C (1 <= C <= 75) columns. As we all know, Farmer John is quite the expert on cow behavior, and is currently writing a book about feeding behavior in cows. He notices that if each cow is labeled with an uppercase letter indicating its breed, the two-dimensional pattern formed by his cows during milking sometimes seems to be made from smaller repeating rectangular patterns.

Help FJ find the rectangular unit of smallest area that can be repetitively tiled to make up the entire milking grid. Note that the dimensions of the small rectangular unit do not necessarily need to divide evenly the dimensions of the entire milking grid, as indicated in the sample input below.

Input

* Line 1: Two space-separated integers: R and C

* Lines 2..R+1: The grid that the cows form, with an uppercase letter denoting each cow's breed. Each of the R input lines has C characters with no space or other intervening character.

Output

* Line 1: The area of the smallest unit from which the grid is formed

Sample Input

2 5
ABABA
ABABA

Sample Output

2

Hint

The entire milking grid can be constructed from repetitions of the pattern 'AB'.

 

题目大意:

给定一个 r*c 的字符矩阵,请你求出这个矩阵的最小子矩阵(面积最小),使得这个子矩阵复制若干遍(横向纵向均可)之后能够让原来的矩阵成为这个矩阵的子矩阵.

输出这个矩阵的面积.

 

思路:

在做这个问题之前,先了解一下最小覆盖子串,引用 FJ 的图和话简单介绍一下, 有兴趣可以参考 FJ 的博文.

http://blog.csdn.net/fjsd155/article/details/6866991

当nextn < n - nextn时,如图a,长为next[n]的前缀A与长为next[n]的后缀B相等,故长为n-nextn的前缀C必覆盖后缀B;


当nextn > n - nextn时,如图b,将原串X向后移 n - nextn 个单位得到Y串,根据next的定义,知长为 nextn 的后缀串A与长为前缀串B相等,X串中的长为 n - nextn的前缀C与Y串中的前缀D相等,而X串中的串E又与Y串中的D相等……可见 X串中的长为n-nextn的前缀C可覆盖全串。

那么现在问题是二维的,网上大部分的做法是求 lcm, 后来才发现是错的....

我的一点想法, 不知正确与否. 有个人的博客上面说这个是错的....但是他的描述似乎又和这个做法差不多?

就是求出这一堆串的最大值....然后就ok了(当最小覆盖串的长度为 L 时,[ L+1, N ] 都是可行长度的覆盖串的串长).

我想,因为某个串 x 的最小重复字串的长度是 Lx 那么答案一定不小于 Lx 但是一个数和其他数的 lcm 不会比这两个数中最大的那个数小.... 所以答案是取最大值.

代码:

 1 #include<cstdlib>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn = 10010, maxm = 80;
 7 int n,m,col = 1,row = 1;
 8 char str[maxn][maxm];
 9 int fail[maxn];
10 int getfail(int x,int y,int tx,int ty){
11     fail[0] = -1;
12     int px = x, py = y,i,j;
13     x += tx, y += ty;
14     for(i = 1,j = 0; str[x][y];)
15         if(j == -1 || str[x][y] == str[px][py]){
16             i++, j++, fail[i] = j;
17             x += tx, y += ty; px += tx, py += ty;
18         }
19         else{
20             px -= tx * (j - fail[j]); py -= ty * (j - fail[j]);
21             j = fail[j];
22         }
23     return i - fail[i];
24 }
25 int main()
26 {
27     freopen("grid.in","r",stdin);
28     freopen("grid.out","w",stdout);
29     scanf("%d %d\n",&n,&m);
30     for(int i = 0; i < n; ++i) scanf("%s",str[i]);
31     for(int i = 0; i < n; ++i){
32         int t = getfail(i,0,0,1);
33         col = max(col, t);
34     }
35     for(int i = 0; i < m; ++i){
36         int t = getfail(0,i,1,0);
37         row = max(row, t);
38     }
39     printf("%d\n",row * col);
40     return 0;
41 }
View Code

 

posted @ 2015-01-14 09:24  Mr.Ren~  阅读(77)  评论(0编辑  收藏  举报