計蒜客 - 猴子打字
有乙個有趣的定理:無限猴子定理(infinite monkey theorem),它的表述如下:讓乙隻猴子在打字機上隨機按鍵,當按鍵次數達到無窮時,幾乎必然能夠打出任何給定的文字。
給出一篇猴子打出的「文章」,並給定乙個由若干個詞組成的詞典,問猴子一共打出了多少個在詞典**現的詞。
輸入格式
第一行乙個整數 n(1
≤n≤10000
)n(1\leq n\leq 10000)
n(1≤n≤
1000
0),表示詞典中單詞的個數。
接下來 n
nn 行,每行乙個僅由小寫字母組成的單詞,長度不超過 50
5050
。最後一行是一篇僅由小寫字母組成的文章,長度不超過 1000000
1000000
100000
0。
5
jskjisuan
suantou
love
program
jisuantouisprogramming
輸出格式
一行乙個整數,表示答案。
3
這道題是 ac 自動機的模板題,直接套用模板就好了。
ac 自動機演算法主要依靠構造乙個有限狀態機(類似於在乙個 trie 樹中新增失配指標)來實現。
這些額外的失配指標允許在查詢字串失敗時進行回退(例如設 trie 樹的單詞cat
匹配失敗,但是在 trie 樹中存在另乙個單詞cart
,失配指標就會指向字首ca
),轉向某字首的其他分支,免於重複匹配字首,提高演算法效率。
如果對 kmp 演算法了解的話,應該知道 kmp 演算法中的next
函式的用途。kmp 中我們用next
函式記錄了失配後應該調整到的位置,ac 自動機的失敗fail
指標具有同樣的功能,也就是說當我們的模式串在 trie 上進行匹配時,如果與當前節點的關鍵字不能繼續匹配,就應該去當前節點的失敗指標所指向的節點繼續進行匹配。
#include const int maxc = 26;
const int maxn = 1000007;
const int max_word_len = 57;
using namespace std;
// 資料量比較大,可能需要開成全域性的,或者動態的,直接放在結構體中,也許會超記憶體
int child[maxn][maxc], fail[maxn], sta[maxn], q[maxn];
int tot;
/** * ac 自動機
*/struct ac_automaton
/*** 插入單詞
* @param ch 單詞,該單詞下標從 1 開始
*/void insert(char* ch)
sta[p]++;
}/**
* 對插入了單詞的字首樹構造失敗指標
*/void build() }}
/*** 查詢給定的字串中,一共有多少個單詞是出現在詞典中的
* @param ch 給定的字串,該字串下標從 1 開始
* @return 該字串中有多少單詞是出現在詞典中的
*/int solve(char* ch)
}return ret;
}}t;int main()
// 根據字首樹中的單詞構造失敗指標,即構造字典
ac->build();
// 給定的文章,下標從 1 開始
計蒜客 2019計蒜之道D
題意 現在給定你乙個字串 s ss 以及乙個整數 k kk,請求出 s ss的字典序最小的長度為 k kk的子串行。資料範圍 0 s 5000000 00 s 5000 000 樣例輸入 helloworld 5樣例輸出 ellld思路 假如我們先不考慮長度為k的限制我們應當怎麼做?我們以樣例為例子...
計蒜客 解碼
蒜頭君自己發明了一種字串的編碼方式,對於只含有大小寫字母的字串,可以用數字來表示括號裡面的串連續出現的次數 數字有可能超過一位數 比如a abcd 2等價於aabcdabcd。特別地,如果數字前面沒有括號,表示緊貼數字的前面的 乙個字母 出現的次數。比如abc2表示abcc。為了降低解碼的難度,蒜頭...
計蒜客 郊遊
蒜頭君成為了計蒜客附屬幼兒園的一名老師,乙個陽光明媚的週末,蒜頭君帶領著小朋友們去野外郊遊。一共有 2n2n 個小朋友,正好是 n n 個男孩和 n n 個女孩。蒜頭君讓小朋友分組玩遊戲,每組乙個男孩和乙個女孩,但是有些女孩比較討厭某些男孩,不願意和他們分在一組,男孩覺得和誰分在一組都無所謂。你能告...