Loading

最小表示法

最小表示法

感觉这是一个很冷门的算法?

遇到的题不多,但是很有趣。

什么是最小表示法

用来求一个字符串或数列,循环得到的串或数列,字典序最小的是哪个。

如何求最小表示法

  • 定义两个指针 \(i\)\(j\),初始时指向 \(0\)\(1\)
  • 维护一个 \(k\),表示 \(i\) 开头的子串和 \(j\) 开头的子串,现在的前 \(k-1\) 位是相同的。
  • 比较第 \(k\) 位,如果依然相等就 \(k++\)
  • 否则假设更大的那个子串,从它的头指针位置到现在的第 \(k\) 位开头的子串,一定也大于更小的那个子串从它的头指针位置到现在的第 \(k\) 位开头的子串,所以大的那个跳到现在的第 \(k+1\) 位,并重新匹配。(有点像绕口令.....)
  • 如果指针跳的时候 \(i=j\) 了,那么令其中一个再向后跳。

Code

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int n,p,a[N];
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%d",&a[i]);
    int i=0,j=1,k=0;
    while(i<n&&j<n&&k<n)
    {
        if(a[(i+k)%n]>a[(j+k)%n])i=i+k+1,k=0;
        else if(a[(i+k)%n]<a[(j+k)%n])j=j+k+1,k=0;
        else k++;
        if(i==j)i++;
    }
    p=min(i,j);
    for(int i=0;i<n;i++)printf("%d ",a[(p+i)%n]);
    return 0;
}
posted @ 2024-12-02 20:29  AvisD  阅读(34)  评论(0)    收藏  举报