Gym 101667I Slot Machines (2017-2018 ACM-ICPC, Asia Daejeon Regional Contest I題)
阿新 • • 發佈:2018-11-19
傳送門: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; }