標點符號的出現晚於文字的出現,所以以前的語言都是沒有標點的。現在你要處理的就是一段沒有標點的文章。
一段文章t是由若干小寫字母構成。乙個單詞w也是由若干小寫字母構成。乙個字典d是若干個單詞的集合。我們稱一段文章t在某個字典d下是可以被理解的,是指如果文章t可以被分成若干部分,且每乙個部分都是字典d中的單詞。
例如字典d中包括單詞,則文章『whatisyourname』是在字典d下可以被理解的,因為它可以分成4個單詞:『what』, 『is』, 『your』, 『name』,且每個單詞都屬於字典d,而文章『whatisyouname』在字典d下不能被理解,但可以在字典d』=d+下被理解。這段文章的乙個字首『whatis』,也可以在字典d下被理解,而且是在字典d下能夠被理解的最長的字首。
給定乙個字典d,你的程式需要判斷若干段文章在字典d下是否能夠被理解。並給出其在字典d下能夠被理解的最長字首的位置。
輸入檔案第一行是兩個正整數n和m,表示字典d中有n個單詞,且有m段文章需要被處理。之後的n行每行描述乙個單詞,再之後的m行每行描述一段文章。
其中1<=n, m<=20,每個單詞長度不超過10,每段文章長度不超過1m。
對於輸入的每一段文章,你需要輸出這段文章在字典d可以被理解的最長字首的位置。
4 3isname
what
your
whatisyourname
whatisyouname
whaisyourname
14 (整段文章』whatisyourname』都能被理解)6 (字首』whatis』能夠被理解)
0 (沒有任何字首能夠被理解)
這道題是典型的字典樹。我們先從頭預處理可查到的單詞,然後標記單詞結尾的節點的編號,再向後查詢,是否在字典裡,這樣一直下去即可。
1 #include2#define n 1000010
3using
namespace
std;
4int
n,m;
5bool flag[n];//
標記字串中單詞結尾的
6struct
trie//
初始化
14int idx(char
c)15
18void insert(string
s)19
30 u=ch[u][c];31}
32 val[u]=1;//
給單詞結尾打上標記 33}
34void find(string
s)35 45
for(int i=0;i)
4657
}58 printf("
%d\n
",ans);59}
60}tree;
61int
main()
6270
for(int i=1;i<=m;i++)
7175
return0;
76 }
洛谷 P2292 HNOI2004 L語言
ac自動機 dp 洛谷這題資料加強之後用bfs t了最後一兩個點 用了乙個dp陣列做轉移 注意一下字串下標的偏移 因為有了dp陣列 存下trie樹上的結尾結點的字串長度 注意一下ac自動機的空間和dp陣列的空間 其他就沒啥了 include include include include inclu...
題解 P2292 HNOI2004 L語言
這到題一眼看去,似乎就是個ac自動機,然後迅速的打出了ac自動機的板子。最開始我想的是,不就判斷一下長度就行了嗎,把每乙個單詞的長度求出來,在ac自動機的時候每次用當前位置的下標減去單詞長度,如果小於等於目前的字首長度,就更新答案,然後迅速地打出 發現只有70分,仔細思考了一下,發現是因為我沒有讀清...
洛谷 P1437 HNOI2004 敲磚塊
在乙個凹槽中放置了 n 層磚塊 最上面的一層有n 塊磚,從上到下每層依次減少一塊磚。每塊磚 都有乙個分值,敲掉這塊磚就能得到相應的分值,如下圖所示。14 15 4 3 23 33 33 76 2 2 13 11 22 23 31如果你想敲掉第 i 層的第j 塊磚的話,若i 1,你可以直接敲掉它 若i...