现在的位置: 首页 > 综合 > 正文

poj2185

2018年04月04日 ⁄ 综合 ⁄ 共 979字 ⁄ 字号 评论关闭

/*kmp的一道好题,ZOJ1905题的一道升华。

这道题目的核心就在于,先行匹配,取最小公倍数,再列匹配,取最小公倍数,两个一乘就是area。

这题有句话很重要,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.
意思是不需要完全对到,所以对于一个字符串,重叠最小区间就是l-p[l]。*/

#include<cstdio>
int r,c;
int lcm[10010];
char str[10010][80];
int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}
int gao(int a,int b)
{
	return a*b/gcd(a,b);
}
int main()
{
	while(2==scanf("%d%d",&r,&c))
	{
		int f=1;
		for(int i=1;i<=r;i++)
			scanf("%s",str[i]+1);
		for(int i=1;i<=r;i++)
		{
			int p[80];
			p[1]=0;
			int k=0;
			for(int j=2;j<=c;j++)
			{
				while(k>0&&str[i][k+1]!=str[i][j])
					k=p[k];
				if(str[i][k+1]==str[i][j])
				k++;
				p[j]=k;
			}
			lcm[i]=c-p[c];
		}
		int ans=1;
		for(int i=1;i<=r;i++)
		ans=gao(ans,lcm[i]);
		if(ans>c)
		ans=c;
		f*=ans;
		for(int i=1;i<=c;i++)
		{
			int p[10010];
			p[1]=0;
			int k=0;
			for(int j=2;j<=r;j++)
			{
				while(k>0&&str[k+1][i]!=str[j][i])
					k=p[k];
				if(str[k+1][i]==str[j][i])
				k++;
				p[j]=k;
			}
			lcm[i]=r-p[r];
		}
		ans=1;
		for(int i=1;i<=c;i++)
		ans=gao(ans,lcm[i]);
		if(ans>r)
		ans=r;
		f*=ans;
		printf("%d\n",f);
	}
	return 0;
}
【上篇】
【下篇】

抱歉!评论已关闭.