Gym 101667I Slot Machines (2017-2018 ACM-ICPC, Asia Daejeon Regional Contest I题)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39396954/article/details/81665376

传送门:http://codeforces.com/gym/101667

Problem I Slot Machines Time Limit: 2 Seconds

题意:数组a有n个数字,数字范围0~999999希望求一组最小的k+p,使得任意i>k,都有a[i]=a[i+p],若两组k+p大小相等,取p较小的

思路:p为循环节,也就是说要求最小的周期。将a序列倒序,求出next数组。这里参考了https://blog.csdn.net/infinity_edge/article/details/79079348的题解,这和kmp里的next有些不一样,next[i]代表倒序后的第i位的数字往前可以追溯到第next[i]位(有点难说清)。

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxv=1e6+6;

int a[maxv],b[maxv],nt[maxv];
int n,m,k,p;
int main()
{
    scanf("%d", &n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
		b[n-i+1]=a[i];
	nt[1]=0;
	for(int i=1;i<n;i++)
	{
		int j=nt[i];
		while(j&&b[j+1]!=b[i+1])
			j=nt[j];
		if(b[i+1]==b[j+1])
			nt[i+1]=j+1;
		else
			nt[i+1]=0;
	}
    int ans=inf;
	for(int i=1;i<=n;i++)
	{
		int now=(n-i+1-nt[n-i+1]);
		if(ans>i+now||(i+now==ans&&now<p))
		{
			ans=i+now;
			k=i-1;
			p=now;
		}
	}
    printf("%d %d\n", k, p);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39396954/article/details/81665376