0
点赞
收藏
分享

微信扫一扫

POJ 2185 Milking Grid (矩阵最小循环节KMP)


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

给你一个R*C的字符矩阵,要你求最小的子矩阵,我们能通过不断重复该子矩阵从而得到一个大矩阵把原矩阵包含在内,求这个子矩阵的面积?

 将大矩阵的每一列看成一个字符,然后对该大矩阵的每一列求出next[i],则列最短循环节长度=小矩阵的宽=ans1=c-next[c]。

将大矩阵的每一行看成一个字符,然后对该大矩阵的每一行求出next[j],则行最短循环节长度=小矩阵的高=ans2=r-next[r]。

 最后答案:ans1*ans2即为所求矩阵的面积。

AC代码:
 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<map>
#include<set>
#include<iomanip>
#include<math.h>
using namespace std;
typedef long long ll;
typedef double ld;

char s[10010][100];
int next[10010];
int r,c;
bool str1(int i,int j)//判断第i行和第j行是否相等
{
for(int k=0; k<c; k++)
if(s[i][k]!=s[j][k])
return false;
return true;
}
bool str2(int i,int j)//判断第i列和第j列是否相等
{
for(int k=0; k<r; k++)
if(s[k][i]!=s[k][j])
return false;
return true;
}
int main()
{
while(scanf("%d %d",&r,&c)==2)
{
for(int i=0; i<r; i++)
scanf("%s",s[i]);
next[0]=next[1]=0;
for(int i=1; i<r; i++) //把每行看成一个字符
{
int j=next[i];
while(j&&str1(i,j)==false)
j=next[j];
next[i+1]=(str1(i,j)==true)? j+1 :0;
}
int ans1=r-next[r];
next[0]=next[1]=0;
for(int i=1; i<c; i++) //把每列看成一个字符
{
int j=next[i];
while(j&&str2(i,j)==false)
j=next[j];
next[i+1]=(str2(i,j)==true)? j+1 :0;
}
int ans2=c-next[c];
printf("%d\n",ans1*ans2);
}
return 0;
}

 

举报

相关推荐

0 条评论