BZOJ2882工艺

题目描述

小敏和小燕是一对好朋友。
他们正在玩一种神奇的游戏,叫Minecraft。
他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边。
他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮。
两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一样,那么这两个工艺品就一样漂亮。
题解
最小表示法
做法:维护两个指针i&j,初始时令i=1,j=2。每次比较当前位置是否相同,如果相同就继续比较下一位,如果出现的不一样的地方。
那么假设a[i+k]>a[j+k],那么i~i+k都不可能成为最佳开头,那么直接跳过这一部分就好。
注意当操作到i=j时要让j++,保证我们的比较是合法的。
代码
#include<iostream>
#include<cstdio>
#define N 630009
using namespace std;
typedef long long ll;
int n,a[N];
inline ll rd(){
    ll x=0;char c=getchar();bool f=0;
    while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return f?-x:x;
}
int main(){
    n=rd();
    for(int i=1;i<=n;++i)a[i]=rd();
    for(int i=1;i<=n;++i)a[i+n]=a[i];
    int i=1,j=2,k=0;
    while(i<=n&&j<=n&&k<=n){
        ll delta=a[i+k]-a[j+k];
        if(!delta)k++;
        else{
            if(delta>0)i=i+k+1;
            else j=j+k+1;k=0;
            if(i==j)j++;
        }
    }
    int now=min(i,j);
    for(int i=now;i<=now+n-1;++i)printf("%d ",a[i]);
    return 0;
} 
posted @ 2019-03-04 21:20  comld  阅读(233)  评论(0编辑  收藏  举报