1. 程式人生 > >POJ2185 Milking Grid(KMP)

POJ2185 Milking Grid(KMP)

子矩陣 str currently 滿足 line void tile cte eve

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‘. 題意:在字符矩陣中找出一個最小子矩陣,使其多次復制所得的矩陣包含原矩陣 分析:為了找到最小重復的子矩陣,我們需要找到最小重復的寬度和長度. 最小重復的寬度需要滿足每一行,所以我們枚舉了每種寬度滿足的行數. 最後找到最小重復的寬度. 找最小重復的長度的時候,進行在豎直方向上,對滿足最小重復寬度的前綴進行KMP的next操作 找到最小重復的長度 貼一下一位講解詳細的大佬:http://blog.sina.com.cn/s/blog_69c3f0410100tyjl.html 代碼如下
#include <cstdio>
#include 
<iostream> #include <algorithm> #include <cstring> using namespace std; char str[10010][80]; char a[80]; int f[10010];//用來統計最小重復長度是下標長度的行數有多少. int Next[10010]; int r,c,i,j,p,q,kuan; void getNext() { int j, k; j = 0; k = -1; Next[0] = -1; while(j < r) if(k == -1 ||!strcmp(str[j],str[k])) //
進行多個字符數組之間的KMP操作 Next[++j] = ++k; else k = Next[k]; } int main() { while(scanf("%d%d",&r,&c)!=EOF) { for(int i=0;i<r;i++) scanf("%s",str[i]); memset(f,0,sizeof(f)); for(int i=0;i<r;i++){ memcpy(a,str[i],sizeof(str[i])); for(int j=c;j>0;j--) { a[j]=\0; for(p=0,q=0;str[i][q];p++,q++) { if(p==j)p=0; if(a[p]!=str[i][q])break; } if(!str[i][q])f[j]++;//能夠匹配到字符串末端 即循環節成立,進行計數 } } for(i=1;i<=c;i++) { if(f[i]==r) //求得滿足所有行數的最小重復長度 { kuan=i; break; } } for(i=0;i<r;i++)str[i][kuan]=\0;// 滿足最小重復的寬度的前綴中進行KMP操作 getNext(); printf("%d\n",(r-Next[r])*kuan);//長*寬 即為最小的重復子矩陣 } return 0; }

POJ2185 Milking Grid(KMP)