最小表示法 例子

2021-09-25 21:41:54 字數 1290 閱讀 3875

字串的最小表示法,就是對於乙個字串,可以將它的最後一位放到第一位來,依次類推,一共有n種變形,n為字串長度

例如:s=「00ab」

變形有(省略引號)b00a ab00 0ab0

一共4種

那麼找到其中字典序最小的乙個,用的演算法便是這個。

定義三個指標,i,j,k

初始i=0;j=1;k=0

首先,如果s[i]如果s[i]>s[j]那麼也很明顯i=j++

省下的就是如果s[i]==s[j]的時候。

這時候有乙個性質就是在i和j之間的所有的字元一定是大於等於s[i]的

另k=0,迴圈尋找第乙個s[i+k]!=s[j+k]的位置

如果s[i+k]為什麼呢?

首先s[i]到s[i+k-1]一定是大於等於s[i],因為如果其中有乙個數小於s[i],那麼這個數一定在s[j]到s[j+k-1]中存在,又因為必定有乙個會在後面,所以如果s[j]先碰到了,那麼一定不會繼續到k的位置的,所以一定不存在比s[i]小的字元。

所以從其中的任意乙個字元開始當作起始點,都不會比現在更小,所以只有從選出來的序列的後面那乙個字元開始才有可能會是最小。

所以j+=k+1

如果序列中某個數和s[i]相等的話,那麼一定會有之前或者以後再這個位置起始過,所以不需要再從這個位置進行起始。

因為在這裡i和j是等價的,i在前和j在前的結果是一樣的,所以i和j的處理是相同的,下面就不仔細的進行講解了,直接貼**:

還有就是如果i==j那麼讓j++就可以回到原先的狀態了

最後的時候,肯定是小的不會動,而大的會不停的向後移動,所以最後只需要輸出i和j最小的乙個即可。

int get_min()

}return i >j ?j :i;

}

栗子

#include#include#include#includeusing namespace std;

const int maxn = 5e5+10;

int n;

char a[maxn],st[maxn];

int get_min()

}return i>n;

cin>>a;

int p = get_min();

int i;

for(i=p; ist[i-p] = a[i%n];

for(i=0; iif(i!=n)

printf("no\n");

else

printf("yes\n");

return 0;

}

進退法例子

進退法例子,遇到具體問題還得修改,以後最速下降梯度法的梯度方向是變化的,這是其中乙個要考慮的改變。進退法具體演算法 實現 include stdafx.h include include include define n 2 using namespace std float testfunctio...

回溯法 例子

一句話開場 回溯法就是對隱式圖的深度優先搜尋 bool finished false 是否獲得全部解?backtrack int a,int k,data input int c maxcandidates 這次搜尋的候選 int ncandidates 候選數目 int i counter if ...

Dinic演算法例子

寫法 1 用鄰接矩陣儲存各個流的起點終點 2 用bfs把圖分出層次 記錄到各個點需要流幾次 3 用dfs對圖找出增廣路進行流量擴充 注意反向流要記錄成容量為0的路徑,更新正向流時也要更新反向流 教材361頁 includeusing namespace std struct edge edge ed...