hdu3746

题意:给你一个串,要你在串头或尾添加最少的字符,使得该串至少有2个循环节,问你最少需要加几个字符.

思路:基于KMP的next数组,求出模式串的next数组后,再根据KMP定理:

KMP最小循环节、循环周期:

定理:假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0…len-next[len]-1]。

(1)如果len可以被len - next[len]整除,则表明字符串S可以完全由循环节循环组成,循环周期T=len/L。

(2)如果不能,说明还需要再添加几个字母才能补全。

需要补的个数是循环个数L-len%L=L-(len-L)%L=L-next[len]%L,L=len-next[len]。

#include <string.h>
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int maxn=1e6+10;
char pat[maxn];
int nxt[maxn];
void getnext(int l)
{
	int i=0,j=-1;
	nxt[0]=-1;
	while(i<l)
	{
		if (j==-1||pat[i]==pat[j])
		{
			i++,j++;
			nxt[i]=j;
		}
		else
		j=nxt[j];
	}
}
int main()
{
	int i,j,n,t,l,len;
	scanf("%d",&t);
	while(t--)
	{

		scanf("%s",pat);
		l=strlen(pat);
		
		getnext(l);
		len=l-nxt[l];//循环节长度 
		if (nxt[l]==0)
		{
			printf("%d\n",l);
			continue;
		}
		if (l%len==0)
		printf("0\n");
		else
		printf("%d\n",len-l%len);
	}
	return 0;
}
posted @ 2021-01-24 18:26  索饮  阅读(51)  评论(0编辑  收藏  举报