[POJ]2185 真正的正解

来源:互联网 发布:eviews导入数据显示na 编辑:程序博客网 时间:2024/06/08 06:56
Milking Grid
Time Limit: 3000MS Memory Limit: 65536KTotal Submissions: 8812 Accepted: 3839

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 5ABABAABABA

Sample Output

2

Hint

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

Source

USACO 2003 Fall

[Submit]   [Go Back]   [Status]   [Discuss]

Home Page   Go Back  To top


所谓正解?(伪)

    1.求的所有行的循环节求max值,再求列的循环节的max值,两者相乘.
    反例: 
    2 6
    ABCDAB
    ABCABC 
    用1求出来是8.实际上是12.
     
    2.将循环节求最小公倍数,若大于行(列)数就变为行(列)数.
    反例:
    2 8
    ABCDEFAB
    ABABAAAB
    用2算出来因为行的循环节为5,6,最小公倍数30,因为大于8就转化为8,再乘上竖着的2,答案为16.
    实际上答案应该是12,为:
    ABCDEF
    ABABAA
    事实证明,POJ的数据太水了...网上很多题解都是错误的.

正解(真)

    我们对与行和列进行hash操作.我们首先将所有列hash,那么每一列变成一个数,也就将矩阵压缩成了一行.再进行kmp的next预处理,求出循环节.再对行hash,列kmp,求出循环节,相乘即可.
    正确性?
    因为对于一串独立的字符串,他的hash值是唯一的.那么在行kmp的时候一列成了一个数值,那么两列数值相同当且仅当两列字符相同.因为最小矩阵覆盖不会出现错开的情况,是对齐的,那么一列可能穿过多次最小矩阵,那在一个最小矩阵长度之后的那一列,应该是与他相同的,因为我们是对齐了的.对行同理.
    话说要是不对齐该怎么搞...

代码

#include<stdio.h>#include<cstring>const int maxn=10005;unsigned long long base=10007;int T,r,c,ans,len,nxt[maxn];char s[maxn][105];unsigned long long temp[maxn],line[maxn],row[maxn];inline int kmp_nxt(){    int i=0,j=-1;nxt[0]=-1;    while(i<len){        if(j==-1||temp[i]==temp[j]) i++,j++,nxt[i]=j;        else j=nxt[j];}return len-nxt[len];}inline void solve(){scanf("%d%d",&r,&c);    for(register int i=0;i<r;i++) scanf("%s",s[i]);    for(int i=0;i<c;i++) for(int j=0;j<r;j++) line[i]=line[i]*base+s[j][i];    for(int i=0;i<c;i++) temp[i]=line[i];    len=c,ans=kmp_nxt();    for(int i=0;i<r;i++) for(int j=0;j<c;j++) row[i]=row[i]*base+s[i][j];    for(int i=0;i<r;i++) temp[i]=row[i];len=r,ans*=kmp_nxt();    printf("%d\n",ans);}int main(){    solve();}


     
原创粉丝点击