【KMP求循环节】Gym - 101667I - Slot Machines

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

题目链接<https://cn.vjudge.net/problem/Gym-101667I>


题意:

每次给出数组T[]。问要满足从第k+1个数开始,数组T开始以p个数为一个循环,k+p最小是多少。如果存在多个k+p最小,输出p最小的方案。


题解:

首先要明白它所说的循环是什么,abcabc是以abc为一个循环。abcab也可以是以abc为一个循环,只是最后的c没有。

做法就是将数组倒过来,求一次kmp的next数组。利用结论p=i-next[i](循环节长度==当前长度 - next值)。然后枚举k的长度,就可以出结果了。


#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=5e6+7;
int a[N],next[N],n;
void getnext(){
    for(int i=0,j=2;j<=n;++j){
        while(i&&a[j]!=a[i+1]) i=next[i];
        if(a[j]==a[i+1]) i++;
        next[j]=i;
    }
}
int main(){
    scanf("%d",&n);
    for(int i=n;i>=1;i--)
        scanf("%d",&a[i]);
    getnext();
    int ak=n,ap=n;
    for(int i=1;i<=n;i++){
        int p=i-next[i],k=n-i;
        if(p+k<ak+ap) ak=k,ap=p;
        else if(p+k==ak+ap&&p<ap) ak=k,ap=p;
    }
    printf("%d %d\n",ak,ap);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/monochrome00/article/details/81782617
今日推荐