只能說我剛學完最小表示法,現在寫一下自己的感想,因為不懂怎麼用csdn,所以只有文字描述和**
#include
#include
#include
#include
#include
using namespace std;
///最小表示法
/*最小表示法就是表示乙個迴圈的字串的最小表示
例如:字串cbabc的最小表示為abccb,就是從第3個字母開始
現在使用兩個變數 u,v(無論如何確保 u < v)表示在比較的開始位置,字串為s,長度為n
使用k表示從u和v開始的第k個位置的字母(每次比較k從0開始)
如果s[(u + k)%n] == s[(v + k)%n], 那麼k++
如果k == n,那麼直接返回u或則v
當s[(u + k)%n] < s[(v + k)%n] 時,那麼就表示u開頭的字母比較小 v就可以直接等於v + k + 1
為什麼不能是v ~ v + k + 1之間的乙個數呢,其實很簡單,
因為當我們隨意選擇v ~ v + k + 1其中乙個數為字串的開始位置是時,
假設這個數為v + i,那麼以u + i為開始的字串必然小於v + i的字串
而且u + i為開頭的字串也必然小於以u開頭的字串(
證:假設u + i <= v,那麼我們可以知道 u < v,而且以u~v之間的數開頭的字串必然小於以u開頭的字串
因為如果中間有比u小的字串,那麼v是必然經過這個數的
當u + i > v時,你可以知道u + i的字串必然小於u+i-(v-u)的字串,而u+i-(v-u)的字串又小於u的字串
所以 v就可以直接等於v + k + 1
當s[(u + k)%n] > s[(v + k)%n] 時,我們可以知道v的字串比較小
因為以u~v之間的乙個數開頭的字串必然小於以u開頭的字串,而u的字串小於v的字串
所以如果u + k + 1 <= v, 那麼u 直接可以等於v + 1
同理,如果u + k + 1 > v,那麼u 直接可以等於u + k + 1
以上*/
const int m = 1e5 +5;
char s[m];
int n;
int min_string()
if(u > v) swap(u,v);
}return u;}//
int main()
return 0;
}
學習筆記 最小表示法
最小表示法 用於解決字串s的迴圈同構串中字典序最小的那個,稱為s的最小表示。eg.s abcd 則其迴圈同構串為 abcd dabc cdab bcda 最小的為 abcd 演算法思路 因為迴圈同構問題,所以可以先複製乙份s到s後邊,形成ss。之後雙指標i,j向後掃瞄,i,j所指代表以i,j為開始的...
學習筆記 最小表示法
給定乙個長度為n,可旋轉的字串環,求從哪個位置斷開的長度為n的字串字典序最小 大 以最小為例,最大同理 bzoj1398 vijos1382尋找主人 necklace 當求出最小表示法之後,掃一遍即可比較兩個不可翻轉的環是否本質相同,比較本質應該是其常見用途吧 1 include2 include3...
學習筆記 最小表示法
一 最小表示法解決的問題 找到乙個字串的迴圈同構串中字典序最小的那個串。二 字串的迴圈同構 比如長度為5字串 abcde 它的5個迴圈同構串有 abcde,bcdea,cdeab,deabc,eabcd 其中字典序最小的串為 abcde 三 求 abcde 的字典序最小的迴圈同構串 1.把 abcd...