题目链接 HDU1298
【题意】给出n(<=1000)个单词以及其出现概率值,每个单词的出现概率又是所有到这个位置的前缀之和,比如
or 2,np 1,nh 3,则串n出现概率为1+3,nh为3,np为1,o为2,or为2;然后求出每次输入手机键盘按钮时对应的概率最大的子串(不一定要出现的字符串,他们前缀都可以)。
【分析】一开始题意理解错了,以为概率为路径之和,知道题意后,还是蛮好写的,只要把字典树的查询改一下,用dfs完成,每次控制下可以查询的字符串(手机键盘数字对应的3,4个字母)就可以暴搜了。
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <map>
//#include <unordered_map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
#define rep(i,a,n) for(int i = a; i < n; i++)
#define repe(i,a,n) for(int i = a; i <= n; i++)
#define per(i,n,a) for(int i = n; i >= a; i--)
#define clc(a,b) memset(a,b,sizeof(a))
const int INF = 0x3f3f3f3f, MAXN = 1010;
int tree[MAXN<<5][30], val[MAXN<<5], cnt;
void init()
{
clc(tree[0],-1);
cnt = 1;
}
void insert(const char *s, int v)
{
int u = 0, n = strlen(s);
rep(i,0,n)
{
int c = s[i]-'a';
if(-1 == tree[u][c])
{
clc(tree[cnt],-1);
val[cnt] = 0;
tree[u][c] = cnt++;
}
u = tree[u][c];
val[u] += v;
}
}
void get_num(int &si, int &len, int num)
{
if(num <= 6)
{
si = (num-2)*3;
len = 3;
return;
}
if(7 == num)
{
si = 15;
len = 4;
return;
}
if(8 == num)
{
si = 19;
len = 3;
return;
}
si = 22, len = 4;
}
char pt[110], ans[110];
int mx;
void query(char *s, int u, int cnt, int len)
{
if(cnt == len)
{
if(mx < val[u])
{
strcpy(ans,pt);
mx = val[u];
}
return;
}
//得到按键对应的字母
int si, n;
get_num(si,n,s[cnt]-'0');
rep(i,0,n)
{
int c = si+i;
pt[cnt] = c+'a', pt[cnt+1] = 0;
if(-1 == tree[u][c]) continue;
query(s,tree[u][c], cnt+1, len);
}
return;
}
int main()
{
#ifdef SHY
freopen("e:\\1.txt", "r", stdin);
//freopen("e:\\out.txt","w",stdout);
#endif
int t, count = 0;
scanf("%d%*c", &t);
while(t--)
{
int n, v;
char s[110];
scanf("%d%*c", &n);
init();
rep(i,0,n)
{
scanf("%s %d%*c",s, &v);
insert(s,v);
}
int m;
scanf("%d%*c", &m);
printf("Scenario #%d:\n", ++count);
rep(i,0,m)
{
scanf("%s", s);
int len = strlen(s);
s[len-1] = 0;
bool end = false;
rep(i,1,len)
{
if(!end)
{
mx = 0;
query(s,0,0,i);
if(mx)
puts(ans);
else
puts("MANUALLY"), end = true;
}
else
puts("MANUALLY");
}
putchar('\n');
}
putchar('\n');
}
return 0;
}