最小表示法

推荐blog:https://www.luogu.com.cn/blog/new2zy/solution-p1368

只进行进一步的解释:

若i,j的位置如图下所示时

若i,j之后都相同,直至k==n,会不会错过更小的值,但此时程序的运行却结束了

不会的

若图片中的粉色方块为“错过的”最优值

那么,其实因为i,j之后的部分都相等

所以

其实在i,j之间的部分同样会这样的最优值,如图上的粉色部分

但因为它在j之前,所以其实这一部分已经被处理过了,

若它真的是最优值,那么j或者是i就不会往后移,而将它舍弃了

推荐题目:【模板】最小表示法

#include<bits/stdc++.h>
using namespace std;
int a[300005],n;
int find_Min(){
    int i=0,j=1,k=0;
    while(i<n&&j<n&&k<n){
        if(a[(i+k)%n]==a[(j+k)%n])k++;
        else {
            if(a[(i+k)%n]<a[(j+k)%n])j=j+k+1;
            else if(a[(i+k)%n]>a[(j+k)%n])i=i+k+1;
            if(i==j)i++;
            k=0;
        }
    }
    return min(i,j);
    //考虑while被停止的情况,
    //因为k>=n而停则取谁都行
    //因为j>=n而停则说明j刚被更新,是因为j不如i了才更新
    //因为i>=n而停同理
}
int main(){
    int i,ans;
    scanf("%d",&n);
    for(i=0;i<n;i++)scanf("%d",&a[i]);
    ans=find_Min();
    for(i=0;i<n;i++)printf("%d ",a[(i+ans)%n]);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Jessica-Cao/p/13892282.html