題意:
原來的按鍵手機都一般是九鍵,九鍵輸入英文很麻煩,例如要鍵入「hello」,必須按兩次鍵4、兩次鍵3、三次鍵5、三次鍵5,最後按三次鍵6。
現有一種新的輸入方案名叫「t9」,只需要不重複地按鍵,軟體就會使用內建的字典來查詢最可能的與輸入匹配的單詞。例如,輸入「hello」,只要依次按下4,3,5,5,6各一次即可。當然,這也可能是「gdjjm」一詞的輸入,但是因為這不是乙個合理的英語單詞,所以可以安全地忽略它。通過排除所有其他不可能的解決方案,並且只考慮適當的英語單詞,這種方法可以大大加快簡訊的寫作速度。當然,如果這個詞不在軟體內建的字典中(比如名字),那麼它必須再次使用多次按鍵的方式輸入。
現在給你「t9」的字典,包含 w(0≤w≤1e3) 個互不相同的字串(串長不超過 100,已經按字典序公升序排序),以及他們的出現概率 p。又給出 m 次打字操作,每次輸入包含不超過 100 個數字的 2∼9 數字串,代表依次按鍵,最後跟乙個 1 代表結束本次打字。
對「字元組合」的概率,定義為所有以該字元組合為字首的單詞的出現概率之和。例如,如果字典包含三個單詞「hell」,「hello」和「hellfire」,則字元組合「hell」的概率是這些詞的概率之和。如果某些組合具有相同的概率,則您的程式是選字典序最小的。
思路:因為已經排好序了,我們先遍歷一遍計算出每個字首的概率和,把每個字首的概率和存在公共字首的字典序最大的那個字串裡,
然後插入到字典樹中
我們用每個字母對應的數字來建樹,但是由於每個數字對應3-4的字母,所以我們在該節點中存:到目前為止 概率最大的串,建樹的過程中概率高的覆蓋低的就可以了。
查詢的時候查到哪輸出哪
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define inf 0x3f3f3f3f
using
namespace std;
const
int maxn=
1e5+5;
int trie[maxn][15
],idx;
char cun[
1005][
105]
;char mp=
"22233344455566677778889999"
;int nowval[maxn]
;int val[
1005][
105]
;void
insert
(char s,
int x)}}
void
query
(char s)
u=trie[u]
[v];
printf
("%s\n"
,cun[u]);
}for
(;s[i]
;i++
)printf
("manually\n");
printf
("\n");
}char str[
1005][
105]
;void
init()
intmain()
for(
int i=
1;i)else
break;}
}for
(int i=
0;i)insert
(str[i]
,i);
scanf
("%d"
,&n)
;printf
("scenario #%d:\n"
,ok++);
for(
int i=
0;i)printf
("\n");
}return0;
}/*12
give 13
integer 6
14681
*/
POJ 1451 T9 (字典樹好題)
背景 為了方便九宮格手機使用者發簡訊,希望在使用者按鍵時,根據提供的字典 給出字串和頻數 給出各個階段最有可能要打的單詞。題意 首先給出的是字典,每個單詞有乙個出現頻率。然後給出的是詢問,每個詢問有乙個數字字串,代表在手機上按了哪些鍵,以1結束。問按鍵的過程中最可能出現的單詞分別是哪些。思路 搞了很...
POJ 1451 T9 字典樹 優先佇列
題意 給你一些單詞 和優先值 然後當你按下數字的時候首先會出現哪個單詞 就是我們平時手機的按鍵 思路 建一顆字典樹 因為按乙個數字對應多個字母 那麼就有多種情況 我們要輸出權值最大的乙個 我用了優先佇列 這裡每個字首的優先值是所有單詞優先值的和 例如abc 5 abd 6 acd 7 那麼a這個字首...
hdu2846(字典樹好題)
字典樹的好題 題意 給你n個串,然後又q次詢問,輸出n個串中包含改串的個數 思路 這題非常考驗個人的分析能力,最初的想法是用ac自動機或者是字尾陣列做,但有感覺不可行,最後看了題解才知道要用字典樹,對n個串的子串的字首建立字典樹,注意 同乙個串可能有相同的子串,所以要有個flag標記。首先要注意的是...