题意:题目说的是在那遥远的星球有一款叫诺基亚的手机,键盘采用题目的图的样式。给定n个单词的出现的概率,规定是相加的比如hell出现为4,hello概率为3则hell的概率为7。现在给定m次输入的格式,根据概率问每一次输入能够得到的字符串是什么
思路:我们把n个单词建立成一棵字典树,然后我们对每一次的输入进行搜索,因为一个数字对应有好几种的可能值,然后把概率最大的字符串保存为ans即可
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1010;
const int N = 110;
const int M = 26;
struct Node{
int mark;
Node* child[M];
};
Node node[MAXN*N];
Node* root;
int pos , maxVal;
char ans[N];
int map[] = {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};
Node* newNode(){
node[pos].mark = 0;
for(int i = 0 ; i < M ; i++)
node[pos].child[i] = NULL;
return &node[pos++];
}
void insert(char *str , int p){
Node* s = root;
int len = strlen(str);
for(int i = 0 ; i < len ; i++){
int num = str[i]-'a';
if(s->child[num] == NULL)
s->child[num] = newNode();
s = s->child[num];
s->mark += p;
}
}
void search(Node* s , char* str , char *tmp , int pos , int len){
if(s == NULL)
return;
if(pos == len){
if(s->mark > maxVal){
maxVal = s->mark;
memcpy(ans , tmp , sizeof(ans));
}
else if(s->mark == maxVal){
if(strcmp(ans , tmp) > 0)
memcpy(ans , tmp , sizeof(ans));
}
return;
}
int num = str[pos]-'0';
for(int i = 0 ; i < M ; i++){
if(map[i] == num){
tmp[pos] = i+'a';
search(s->child[i],str,tmp,pos+1,len);
tmp[pos] = '\0';
}
}
}
void solve(){
int n;
char str[N];
char tmp[N];
char tmpAns[N];
scanf("%d" , &n);
while(n--){
scanf("%s" , str);
int len = strlen(str)-1;
for(int i = 0 ; i < len ; i++){
memcpy(ans , "MANUALLY" , sizeof(ans));
memcpy(tmp , str , sizeof(tmp));
tmp[i+1] = '\0';
maxVal = 0;
memset(tmpAns , '\0' , sizeof(tmpAns));
search(root , tmp , tmpAns , 0 , i+1);
printf("%s\n" , ans);
}
puts("");
}
}
int main(){
int cas , m , p;
int Case = 1;
char str[N];
scanf("%d" , &cas);
while(cas--){
printf("Scenario #%d:\n" , Case++);
pos = 0;
root = newNode();
scanf("%d" , &m);
for(int i = 1 ; i <= m ; i++){
scanf("%s %d" , str , &p);
insert(str , p);
}
solve();
puts("");
}
return 0;
}