Hdu 4333(擴充套件KMP)

2022-05-24 15:51:11 字數 1092 閱讀 6192

2014-12-17 01:34:48

思路:仔細思考,發現如果用擴充套件kmp,求出每個位置到末尾的最大字首匹配長度,比如1~100,位置50能匹配到75,那麼當我們把50~100移動到開頭。前25個字元是一樣的,需要比較的是第26個字元(也就是移動前的第76個字元),所以如果設next[i]為位置 i 到末尾的最大字首匹配長度,需要比較的就是s[i + next[i]]與s[next[i]],我們發現如果i + next[i] < len,那麼s[i + next[i]] 與 s[next[i]]必然不同,但如果i + next[i] == len,則需要不斷地比較i + next[i] 與 next[i]、i + next[i] + 1 與 next[i] + 1。。。。知道找到不同,這顯然效率不夠。我們可以把原先的串先複製一倍長度,這樣就可以把「不斷比較的過程省去」。

如果next[i] >= len,說明移動後相等,如果s[i + next[i]] > s[next[i]] 說明移動後數更大,如果s[i + next[i]] < s[next[i]] 說明移動後數更小 、

最後還要注意:題目中說數字不能重複,所以要用kmp求出最大迴圈節,以去重(具體求最大迴圈節方法見**)

1 #include 2 #include 3 #include 4 #include 5

using

namespace

std;

6const

int maxn = 200010;7

8int

t,len,ans1,ans2,ans3;

9int

next[maxn],p[maxn];

10char

s[maxn];

1112

void

get_p()20}

2122

void

ex_kmp()

37else next[i] =l;38}

39}4041

intmain()

59 printf("

case %d: %d %d %d\n

",tt,ans1,ans2,ans3);60}

61return0;

62 }

hdu4333 擴充套件kmp

題意 給定乙個數字 10 100000,一次將該數的第一位放到放到最後一位,求所有組成的不同的數比原數小的個數,相等的個數,大的個數 分析 由於輸入的數太大了,只能當作字串處理,將輸入的原串貼上在後面,這樣就可以對原串進行ekmp,最終只要統計從第i個位置開始的extend i 如果 len則從第i...

hdu4333 擴充套件kmp演算法

原題鏈結 思路比較簡單。把原串擴大一倍,然後以原串為模板串,用擴充套件kmp演算法求出每個位置的最大字首即可。wa了一天了,也不知道改了哪個地方就對了 include include define maxl1000100 using namespace std char s1 maxl 2 s2 m...

擴充套件KMP KMP hdu4333

自己就是想不到,智商是硬傷啊 思路 擴充套件kmp能求出乙個串所有字尾串 即s i.len 和模式串的最長公共字首。於是只要將這個串複製一遍,拼接到後面,求出拼接後的串每個字尾與原來串的最長公共字首即可,當公共字首 len時,顯然相等,否則只要比較下一位就能確定這個串與原串的大小關係。至於重複串的問...