vijos-1382 寻找主人

题意:

给出两个相同长度的数字串;

求两个串是否本质相同,相同则输出最小表示;

长度L似乎给的不对,大概是2000000左右吧;


题解:
最小表示法裸题,证明正确性啥的详见论文吧;

这东西大体的思路就是两个指针扫;

相同则累加k,不同就向后跳k+1个;

因为前面那段相同所以就可以由另一个指针去扫,来节约时间;

O(n)这个很显然咯,就一个for循环(笑);

并且每个数都在+++不像kmp还会由next数组回退;

模板别敲错,更别忘了。。


代码:


#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 2100000
using namespace std;
char a[N<<1],b[N<<1];
int len;
int slove(char *s)
{
	int i,j,k,cmp;
	for(i=1,j=2,k=0;i<=len&&j<=len&&k<=len;)
	{
		cmp=s[i+k]-s[j+k];
		if(!cmp)	k++;
		else
		{
			if(cmp>0)	i+=k+1;
			else		j+=k+1;
			if(i==j)	j++;
			k=0;
		}
	}
	return min(i,j);
}
int main()
{
	int i,j,k,s1,s2;
	scanf("%s%s",a+1,b+1);
	len=strlen(a+1);
	memcpy(a+len+1,a+1,sizeof(int)*len);
	memcpy(b+len+1,b+1,sizeof(int)*len);
	s1=slove(a);
	s2=slove(b);
	for(i=s1,j=s2,k=1;i<s1+len;i++,j++)
		if(a[i]!=b[j])
			k=0;
	if(!k)	puts("No");
	else
	{
		puts("Yes");
		a[s1+len]='\0';
		puts(a+s1);
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值