2018.07.17 洛谷P1368 工艺(最小表示法)

传送门
好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现。

首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头尾。然后开始逐位比较,当两个字串同一位置的字符不同时,相对来说字符值较大的指针跳到失配下标的后面一位,如果此时两个指针重合,将其中一个加一。边界条件:两个指针中有一个值大于原数组长度。

代码如下:

#include<bits/stdc++.h>
#define N 300005
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans;
}
inline void write(int x){
    if(x>9)write(x/10);
    putchar((x%10)^48);
}
int n,a[N<<1];
int main(){
    n=read();
    for(register int i=1;i<=n;++i)a[i]=a[i+n]=read();
    int l=1,r=2;
    while(l<=n&&r<=n){
        int p1=l,p2=r;
        while(a[p1]==a[p2])++p1,++p2;
        if(a[p1]>a[p2]){
            l=p1+1;
            if(l==r)++l;
        }
        else{
            r=p2+1;
            if(l==r)++r;
        }
    }
    if(l>n)for(register int i=r,cnt=1;cnt<=n;++cnt,++i)write(a[i]),putchar(' ');
    else for(register int i=l,cnt=1;cnt<=n;++cnt,++i)write(a[i]),putchar(' ');
    return 0;
}

转载于:https://www.cnblogs.com/ldxcaicai/p/9738445.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值