挤奶网格
-
总时间限制:
- 3000ms 内存限制:
- 65536kB
-
描述
-
每天早上奶牛被挤奶的时候,农夫约翰的奶牛会成一个R行,C列的长方形网格(1 <= R <= 10,000,1 <= C <= 75)。据我们所知,约翰i研究奶牛行为上,是一个专家,同时也在编写一个关于如何饲养奶牛的书。他发现如果将每头奶牛用一个大写字母来标识其种类,在挤奶的时候他的奶牛所形成的二维模式似乎有时候是从一些更小的长方形模式重复得来。帮助 寻找最小面积的长方形单位,该长方形单位可以通过重复从而构成整个挤奶网格,注意到这个小的长方形单位的维度并不需要由整个挤奶网格的维度均分得到,具体可以参见示例。
输入
-
第一行: 两个以空格间隔的整数 R和C
第二行到第R+1行:牛形成的网格,每个格子以一个大写字母来表示每个奶牛的种类。这R行中每行包含C个中间没有间隔符的字母。
输出
- 一行,即网格形成所需要的最小单位的面积。 样例输入
-
2 5 ABABA ABABA
样例输出
-
2
提示
- 整个挤奶网格可以从模式 'AB'重复得来。第一行和最后一行的A用模式‘AB’的前缀部分A得到。即求最小覆盖矩阵。
-
-
#include<iostream> #include<cmath> #include<cstring> #include<algorithm> #include<iomanip> #include<queue> #include<stack> #include<vector> #include<set> #include<map> using namespace std; char s[10005][80]; int Next[10005]; int gcd(int x,int y) { if(y==0)return x; else return gcd(y,x%y); } int lcm(int x,int y) { return x*y/gcd(x,y); } int main() { int r,c; cin>>r>>c; for(int i=0;i<r;++i) { for(int j=0;j<c;++j) { cin>>s[i][j]; } } int lcmr=1,lcmc=1; for(int i=0;i<r;++i) { Next[0]=-1; Next[1]=0; for(int j=2;j<=c;++j) { int tmp=Next[j-1]; while(tmp>=0&&s[i][j-1]!=s[i][tmp]) { tmp=Next[tmp]; } Next[j]=tmp+1; } lcmr=lcm(lcmr,c-Next[c]); if(lcmr>=c) { lcmr=c; break; } } for(int i=0;i<c;++i) { Next[0]=-1; Next[1]=0; for(int j=2;j<=r;++j) { int tmp=Next[j-1]; while(tmp>=0&&s[j-1][i]!=s[tmp][i]) { tmp=Next[tmp]; } Next[j]=tmp+1; } lcmc=lcm(lcmc,r-Next[r]); if(lcmc>=r) { lcmc=r; break; } } cout<<lcmr*lcmc<<endl; return 0; }