poj2185 Milking Grid

#挺难的题 数据水 看了几篇题解才确定了正确做法

对于一个长度为n的字符串,kmp一遍,它的最短题目要求的长度为n-nxt[n]
a个不可分割出循环节的字符串连在一起是不可写成b个连在一起的形式的(a,b互质)

但是对于AAAABAAA,符合的长度有5,6,7,8并不全是8-nxt[8]=5的倍数 所以在得出5这个答案后 要把后面三个(AAA)再kmp一次得到1,所以答案为5,5+1,5+1+1,5+1+1+1

由于r<=75用一个数组统计这些长度出现次数 每次+1,最后从小到大扫若某个长度出现了r次就是我们要的答案的宽

然后对于1-r行再kmp得到长 相乘得到答案

代码

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int r,c;
int cnt[80];
string a[10005];
int nxt[10005];
int main()
{
	cin>>r>>c;
	for(int i=1;i<=r;++i)
	{
		cin>>a[i];
		string s=a[i];
		int pt=0;
		while(s.size())
		{
			for(int j=2,k=0;j<=s.size();++j)
			{
				while(k&&s[k+1-1]!=s[j-1])k=nxt[k];
				if(s[k+1-1]==s[j-1])++k;
				nxt[j]=k; 
			}
			int l=s.size()-nxt[s.size()];
			int j;
			for(j=pt+l;j<=a[i].size();j+=l)++cnt[j];
			pt=j-l;
			s=a[i].substr(pt,a[i].size()-pt);
		}
	}
	for(int i=2,j=0;i<=r;++i)
	{
		while(j&&a[i]!=a[j+1])j=nxt[j];
		if(a[i]==a[j+1])++j;
		nxt[i]=j;
	}
	for(int i=1;i<=c;++i)
	{
		if(cnt[i]==r)
		{
			cout<<i*(r-nxt[r])<<endl;
			break;
		}
	}
	return 0;
}
发布了25 篇原创文章 · 获赞 1 · 访问量 315

猜你喜欢

转载自blog.csdn.net/qq_43665203/article/details/104236517