2017-2018 ACM-ICPC, Asia Daejeon Regional Contest:Gym 101667I

mac2022-06-30  27

题目链接:https://codeforces.com/gym/101667/attachments

题意:现在有一个数列,你需要将前 k k k项去除之后剩下的数列形成一个循环数组周期为 p p p,平且要求 k + p k+p k+p最小,当 k + p k+p k+p相等时 p p p最小。

解题心得:找循环节就是 k m p kmp kmp的应用,只不过这个题需要去除前 k k k个,这就可以将数列先翻转,然后再求一个 k m p kmp kmp,直接找就行了。


#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll maxn = 1e6+10; const ll INF = 1e17; int Next[maxn], n, num[maxn]; void init() { scanf("%d", &n); for(int i=n;i>=1;i--) { scanf("%d", &num[i]); } } void cal_next() { int k = 0; for(int i=2;i<=n;i++) { while(k && num[k+1] != num[i]) k = Next[k]; if(num[k+1] == num[i]) k++; Next[i] = k; } } int main() { init(); cal_next(); int ans_p = 1e7, ans_k = 1e7; for(int i=1;i<=n;i++) { int len = i - Next[i], pos = n - i; if(len + pos < ans_p + ans_k) { ans_p = len; ans_k = pos; } else if(len + pos == ans_p + ans_k && ans_p > len) { ans_p = len; ans_k = pos; } } printf("%d %d\n", ans_k, ans_p); return 0; }
最新回复(0)