POJ 2185 Milking Grid 二维KMP

来源:互联网 发布:中国汽车销售数据 编辑:程序博客网 时间:2024/06/06 00:52

点击打开链接

题意:R*C字符矩阵,R<=1e4,C<=75.求出最小子矩阵使得R*C矩阵能被最小子矩阵覆盖.

若为一维,则相当于用kmp求出最小循环节(只要求覆盖,len%(len-next[len])可以不为0)
先对每行求最小循环节xi,子矩形的宽度最小为:xi(i=1~r)的最小公倍数lr.
在对每列求最小循环节yi 子矩形的高度最小为:yi(i=1~c)的最小公倍数lc.

以lr*lc子矩阵为单位显然能覆盖整个字符矩阵

#include <iostream>#include <algorithm>#include <cstring>#include <queue>#include <cstdio>#include <map>#include <vector>using namespace std;typedef long long ll;const int N=1e4+20;const int inf=2e8; char s[N][80];int r,c,fail[N];int gcd(int a,int b){return b==0?a:gcd(b,a%b);}int lcm(int a,int b){return a*b/gcd(a,b);}void Fail_row(int p){fail[0]=-1;int i=0,j=-1;while(i<c){if(j==-1||s[p][i]==s[p][j]){fail[i+1]=j+1;i++,j++;}elsej=fail[j]; }}void Fail_col(int p){fail[0]=-1;int i=0,j=-1;while(i<r){if(j==-1||s[i][p]==s[j][p]){fail[i+1]=j+1;i++,j++;}elsej=fail[j];}}int main(){while(cin>>r>>c){for(int i=0;i<r;i++)scanf("%s",s[i]);int lcmr=1,lcmc=1;for(int i=0;i<r;i++){Fail_row(i);lcmr=lcm(lcmr,c-fail[c]);if(lcmr>=c){lcmr=c;break;}}for(int i=0;i<c;i++){Fail_col(i);lcmc=lcm(lcmc,r-fail[r]);if(lcmc>=r){lcmc=r;break;}}cout<<lcmr*lcmc<<endl;}return 0;}


原创粉丝点击