首先講一下字串的迴圈表示,下面的內容**:最小表示法
「最小表示法」比起動態規劃、貪心等思想,在當今競賽中似乎並不是很常見。但是在解決判斷「同構」一類問題中卻起著重要的作用。
本文即將討論字串中的同構問題,如何巧妙地運用最小表示法來解題呢,讓我們繼續一起思考吧。
到底什麼是迴圈同構的字串呢?
直接舉個例子:
比如 str1 = "abdea" 而字串str2是str1從第i(i>0)個開始將str1從i迴圈到末尾再從頭開始迴圈到i,那麼這兩個字串就是迴圈同構的.比如str2 = "deaab";
那麼什麼是字串的最小表示呢?
比如上面那個str1,就是從str1的同構字串中字典序最小的,那麼str1的最小表示就是"aabde".
如何得到乙個字串的最小表示?
設函式m(s)
返回值意義為: 從
s的第m(s)
個字元引起的
s的乙個迴圈表示是
s的最小表示。
若有多個值,則返回最小的乙個
比如m("bbbaab") = 4; 也就是最小表示為aabbbb,是從字串"bbbaab"的第4個的字元開始的同構字串。
現在換一種思路:
設有字串s1,s2
設u=s1+s1(也就是將s1複製乙份到s1後面)
,w=s2+s2
並設指標
i,j指向
u,w第乙個字元
如果s1和s2
是迴圈同構的,那麼當
i,j分別指向
m(s1),m(s2)
時,一定可以得到
u[i→i
+|s1|-1]=w[
j→j+|s2|-1]
,迅速輸出正確解。
同樣s1和s2
迴圈同構時,當
i,j分別滿足 i
≤m(s1),j≤
m(s2)時,
兩指標仍有機會達到
i=m(s1),j=m(s2)
這個狀態。
問題轉化成,兩指標分別向後滑動比較,如果比較失敗,如何正確的滑動指標,新指標
i』,j』
仍然滿足 i
』≤m(s1),
j』≤m
(s2)
設指標i,j分別向後滑動
k個位置後比較失敗(k≥
0),即有 u[
i+k]≠w[
j+k] 設
u[i+k
]>w[
j+k]
,同理可以討論
u[i+k
]j+k
]的情況。
因為u[x]在u[
i]後(x-i)
個位置,
對應的可以找到在
w[j]
後(x-i)
個位置的
w[j+(x-i)]
, 同樣對應的有
u[x+1]
和w[j+(x+1-i)]
,u[x+2]
和w[j+(x+2)-i]
, 直到u[i+k-1]
和w[j+k-1]。
它們都是相等的, 即有
u[x→i+k-1]=w[j+(x-
i)→j+k-1]。
很容易就得到
u[x→i+k
]>w[j+(x-i)→
j+k]。
所以s1
(x-1)
不可能是
s1的最小表示!
因此m(s1)>
i+k,
指標i滑到
u[i+k+1]
處仍可以保證小於等於
同理,當
u[i+k
]j+k
]的時候,可以將指標j滑到
w[j+k+1]處!
也就是說,兩指標向後滑動比較失敗以後,
指向較大字元的指標向後滑動
k+1個位置。
舉例: 設
s1=『
babba』,
s2=『
bbaba
』。(兩個同構字串)
u=s1+s1='babbababba' w=s2+s2='bbababbaba'
初始化i=0,j=0,k=0;(i作為u的指標,j作為w的指標)
比較失敗時
k=1 (u[i+k]!=w
[j+k]
由於u[i+k]j = 2 i不變(i=0); k=0
繼續比較發現當k=0時u[i+k]>w[j+k],所以i=i+k+1;
i=1,j不變(j=2);k=0;
繼續比較,發現當k=2時u[i+k]>w[j+k]所以i = i+k+1;
i = 4j不變(j=2)k=0;
繼續比較,這個時候就找到了最小表示ababb
#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
const int maxn=10010;
char s[maxn];
int main()
printf("%d\n",min(q,p)+1);
}return 0;
}
最小表示法
最小表示法就是找出字串s的的迴圈同構串中字典序最小的乙個。那麼什麼是迴圈同構串呢。是 設s bcad 且s 是s 的迴圈同構的串。s 可以是 bcad 或者cadb,adbc,dbca 即在字串s中從i 0開始,從i迴圈到字串末尾,再從頭迴圈到i,所形成的字元就是s迴圈同構串。因為這樣的同構串不止乙...
最小表示法
最小表示法 思想 在字串迴圈同構問題中的應用 摘自周源的ppt 前言 最小表示法 比起動態規劃 貪心等思想,在當今競賽中似乎並不是很常見。但是在解決判斷 同構 一類問題中卻起著重要的作用。本文即將討論字串中的同構問題,如何巧妙地運用最小表示法來解題呢,讓我們繼續一起思考吧。到底什麼是迴圈同構的字串呢...
最小表示法
最小表示法與kmp演算法一樣都可以解決字串匹配問題,但效率更高,短,作用更大。最小表示法就是乙個字串的最小字典序。怎麼求乙個字串的最小字典序呢?首先將這個字串擴充套件一倍 建設存在d陣列裡 然後我們用三個指標i 0,j 1,k 0,來尋找最小字典序的開頭字母,為了優於kmp,我們要做到o n i表示...