[Codeforces-Gym] (101667I)Slot Machines ---- KMP求字首最小迴圈節★
阿新 • • 發佈:2018-12-13
題意:
- 給你n個數組成的序列,讓你求從k+1位置開始,序列以p個數為週期。最小的k+p是多少。
做法:
- kmp 演算法的一個應用,即最小迴圈節是i-next[i] (吃了沒文化的虧_(:з」∠)_
AC程式碼:
#include<bits/stdc++.h> #define IO ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define pb(x) push_back(x) #define sz(x) (int)(x).size() #define sc(x) scanf("%d",&x) #define abs(x) ((x)<0 ? -(x) : x) #define all(x) x.begin(),x.end() #define mk(x,y) make_pair(x,y #define fin freopen("in.txt","r",stdin) #define fout freopen("out.txt","w",stdout) using namespace std; typedef long long ll; typedef pair<int,int> PII; const int mod = 1e9+7; const double PI = 4*atan(1.0); const int maxm = 1e5+5; const int maxn = 1e6+5; const int INF = 0x3f3f3f3f; int a[maxn],n; int nex[maxn]; void get_nex() //next 字首陣列 { int k = nex[0] = -1; int i = 0; while(i<n) { if(k<0 || a[i] == a[k]) { i++; k++; nex[i] = k; } else k = nex[k]; } } int main() { // fin; IO; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; reverse(a,a+n); get_nex(); int k,p,ansk = n,ansp = n; for(int i=0;i<n;i++) { p = n-i-nex[n-i],k = i; //理解好題意! //cout<<k<<" "<<p<<endl; if(k+p<ansk+ansp){ ansk = k,ansp = p; } else if(k+p == ansk+ansp && p<ansp){ ansk = k,ansp = p; } } cout<<ansk<<" "<<ansp<<endl; return 0; }