POJ 2752 Milking Grid

来源:互联网 发布:混合视频矩阵 编辑:程序博客网 时间:2024/04/30 08:39

这是数算期末的压轴题,一共只有9个人AC了,而且120+的WA…
看了一下觉得题目还是有点思路的,不过实际做起来还是贡献了无数的WA

如果有一个块可以重复的话,那么这个块中的每一行和每一列都一定可以是重复的,因此用kmp算法求出每个行的最小覆盖长度和每一列的最小覆盖长度,然后分别求最小公倍数

值得注意的是最小公倍数有可能大于r,c,因此在循环计算最小公倍数的时候应该额外判断一下。

#include <iostream>#include <cstdio>#include <memory.h>#include <string.h>using namespace std;#define maxn 10050#define maxc 100int gcd(int a,int b){    return a%b?gcd(b,a%b):b;}int lcp(int a,int b){    return a*b/gcd(a,b);}char m[maxn][maxc]={0};int num[maxn]={0};int main(){    int r,c;    scanf("%d%d",&r,&c);    for(int i=0;i<r;++i){        for(int j=0;j<c;++j){            cin>>m[i][j];        }    }    int mul = 1;    for(int i=0;i<r;++i){        int j=-1;        memset(num,0,sizeof(num));        num[0]=-1;        for(int k=0;k<c;){            if(j==-1||m[i][k]==m[i][j])                num[++k]=++j;            else                 j = num[j];        }        mul = lcp(mul,c-num[c]);        if(mul >= c){            mul = c;            break;        }    }    int mul2 = 1;    for(int i=0;i<c;++i){        int j=-1;        memset(num,0,sizeof(num));        num[0]=-1;        for(int k=0;k<r;){            if(j==-1||m[k][i]==m[j][i])                num[++k]=++j;            else                 j = num[j];        }        mul2 = lcp(mul2,r-num[r]);        if(mul2 >= r){            mul2 = r;            break;        }    }    int a = mul2*mul;    int b = r*c;    printf("%d\n",a>b?b:a);    //system("pause");    return 0;}
0 0
原创粉丝点击