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 5using
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時,顯然相等,否則只要比較下一位就能確定這個串與原串的大小關係。至於重複串的問...