字符串周期--hdu 3746 Cyclic Nacklace


通过这题得出了一个很重要的结论,在用kmp算法求出next数组后,len-next[len]的值就是该字符串的最小循环节,该字符串的其他循环节都是它的倍数,如果len恰好是len-next[len]的整数倍,那么该字符串就是个power string;如果next[len]为0,表示该字符串是非循环的;否则,按照len-next[len]的循环节,补齐最后一个循环节即为使该字符串成为power string的最小添加字符个数

思路:kmp+字符串的最小循环节问题

分析:
1 题目要求的是给定一个字符串,问我们还需要添加几个字符可以构成一个由n个循环节组成的字符串。
2 可知我们应该先求出字符串的最小循环节的长度:假设字符串的长度为len,那么最小的循环节就是t = len-next[len] ; 如果有len%t == 0,那么这个字符串就是已经是完美的字符串,不用添加任何字符;如果不是完美的那么需要添加的字符数就是cir - (len-(len/t)*t)),相当与需要在最后一个循环节上面添加几个。
3 如果t = 1,说明字符串只有一种字符例如“aaa” ; 如果t = m说明最小的循环节长度为m,那么至少还需m个;如果m%t == 0,说明已经不用添加了。

#include<stdio.h>
#include<string.h>
int next[100005];
char str[100005];
int len;
void getnext()
{
	int i,j=0;
	next[1]=0;
	for(i=2;i<=len;i++)
	{
		while(j>0&&str[i]!=str[j+1])
			j=next[j];
		if(str[i]==str[j+1])
			j++;
		next[i]=j;
	}
}
int main()
{
	int i,j,t,n;
	scanf("%d",&n);
	while(n--)
	{  
		scanf("%s",str+1);
		len=strlen(str+1);
		memset(next,0,sizeof(next));
		getnext();
		t=len-next[len];
		
	    if(t!=len&&len%t==0)
		   puts("0");
	   else
		   printf("%d\n",t-next[len]%t);
	}
	return 0;
}
		




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值