题目:
链接:点击打开链接
题意:
求最小覆盖矩阵的面积。
算法:
二维的KMP算法。
思路:
最小覆盖字符串定是串的前缀,我们能够求出没一行的最小覆盖串的长度。然后求每行串的最小公倍数。就能够得到最小覆盖矩阵的长度。同理求的矩阵的宽度。便可得面积。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[10010][80];
int next[10010];
int r,c;
int gcd(int a,int b)
{
return b == 0 ? a:gcd(b,a%b);
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
void get_nextrow(int p)//行串的next数组
{
int i,j;
i = -1;
j = 0;
next[0] = -1;
while(j<c)
{
if(i == -1 || s[p][i] == s[p][j])
{
j++; i++;
next[j] = i;
}
else
i = next[i];
}
}
void get_nextcol(int p)//列串的next数组
{
int i,j;
i = -1;
j = 0;
next[0] = -1;
while(j<r)
{
if(i == -1 || s[i][p] == s[j][p])
{
j++; i++;
next[j] = i;
}
else
i = next[i];
}
}
int main()
{
//freopen("input.txt","r",stdin);
int lcm_r,lcm_c;
lcm_r = lcm_c = 1;
cin>>r>>c;
getchar();
for(int i=0; i<r; i++)
gets(s[i]);
for(int i=0; i<r; i++)
{
get_nextrow(i);
lcm_r = lcm(lcm_r,c-next[c]);
if(lcm_r >= c)
{
lcm_r = c;
break;
}
}
for(int i=0; i<c; i++)
{
get_nextcol(i);
lcm_c = lcm(lcm_c,r-next[r]);
if(lcm_c >= r)
{
lcm_c = r;
break;
}
}
//cout<<lcm_c<<" "<<lcm_r<<endl;
cout<<lcm_c*lcm_r<<endl;
return 0;
}