版权声明:本文为博主原创文章,转载请务必注明出处。 https://blog.csdn.net/wlx65003/article/details/51819723
题目链接
http://poj.org/problem?id=1451
思路
让你模拟手机输入法。
我这里是同步造了两棵字典树,一棵以字母为节点,统计probability,另一棵以键盘数字为节点,存当前按键路径probability最大的词和它的probability。
同步的方法是,用一个映射,将一个单词映射成数字,从而在两棵树之间同步插入。
看了下网上的代码,好像不用第一棵树也能算出probability,直接几个for搞定,代码短很多,哪天试试。
AC代码
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
struct word //trie of word
{
word()
{
for (int i = 0; i < 26; ++i)
next[i] = NULL;
p = 0;
}
~word()
{
for (int i = 0; i < 26; ++i)
{
if (next[i] != NULL)delete next[i];
}
}
int p;
word *next[26];
};
struct num //trie of number
{
num()
{
for (int i = 0; i < 10; ++i)
next[i] = NULL;
p = 0;
}
~num()
{
for (int i = 0; i < 10; ++i)
{
if (next[i] != NULL)delete next[i];
}
}
string s;
int p;
num *next[10];
};
int mp[] = { 2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9 };
void insert_word(string s, int p, word* root_word, num* root_num)//insert word to both tries
{
word *now_word = root_word;
num *now_num = root_num;
for (int i = 0; i < s.length(); ++i)
{
if (now_word->next[s[i] - 'a'] == NULL)
{
now_word->next[s[i] - 'a'] = new word;
}
now_word = now_word->next[s[i] - 'a'];
now_word->p += p;
if (now_num->next[mp[s[i] - 'a']] == NULL)
{
now_num->next[mp[s[i] - 'a']] = new num;
}
now_num = now_num->next[mp[s[i] - 'a']];
string temp_s = s.substr(0, i + 1);
if (now_word->p > now_num->p ||
(now_word->p == now_num->p && temp_s < now_num->s))
{
now_num->p = now_word->p;
now_num->s = temp_s;
}
}
}
void find_num(string s, num* root_num)//search in num trie and print answer
{
num *now = root_num;
for (int i = 0; i < s.length() - 1; ++i)//ignore the end '1'
{
if (now->next[s[i] - '0'] == NULL)
{
for(int j=0 ; j<s.length()-1-i ; ++j)
{
printf("MANUALLY\n");
}
break;
}
now = now->next[s[i] - '0'];
cout << now->s << "\n";
}
}
int main()
{
int T;
scanf("%d", &T);
for (int k = 1; k <= T; ++k)
{
word *root_word = new word;
num *root_num = new num;
int w;
scanf("%d", &w);
while (w--)
{
string s;
int p;
cin >> s >> p;
insert_word(s, p, root_word, root_num);
}
int m;
scanf("%d", &m);
printf("Scenario #%d:\n", k);
while (m--)
{
string s;
cin >> s;
find_num(s, root_num);
printf("\n");
}
printf("\n");
delete root_word;
delete root_num;
}
return 0;
}