HDU3746【KMP】

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3746

【分析】:题目的意思是这这个串里,需要添加多少字符或者不添加,才可以让它里面的循环体成为至少两次的循环。这里需要巧妙用到next数组,并不需要去优化它,因为不优化的时候求的才是前后缀的最大相同字符个数。要有一个循环体的值minlong=strlen(str)-nex[strlen(str)]。不需要增加的情况,就是刚好两次以上的循环,要增加的话,要先计算出不满足循环体多出来的字符个数strlen(str)%minlong,然后让循环体的长度减去这字符个数,就是需要添加来补齐成为一个小循环体。

#include<iostream>
#include<string>
char str[100000+10];
int nex[100000+10];
void getnex(int len)
{
	int i=-1,j=0;
	nex[0]=-1;
	while(j<len)
	{
		if(i==-1 || str[i]==str[j])
		{
			++j;
			++i;
			nex[j]=i;
		}
		else
			i=nex[i];
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	while(n--)
	{
        getchar();
		scanf("%s",str);
		int len=strlen(str);
		getnex(len);
		int minlong=len-nex[len];//得到这个小循环体的值
		if(minlong!=len && len%minlong==0)
			printf("0\n");
		else
			printf("%d\n",minlong-len%minlong);//添加来补齐成为一个小循环体
	}
	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值