版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}