题意:给定字典和每个单词的权值(表示为概率p)m对于每次查询,输出满足条件的概率最大的单词前缀。
根据题意,这题应该是用字典树做的,可惜弱菜还不怎么熟悉字典树,所以就满打满敲,模拟也可以出来。。。
#include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #include<iostream> #include <queue> #include <stack> #include<algorithm> #include<set> using namespace std; #define inf 2147483647 #define eps 1e-8 #define LL long long #define M 1005 #define mol 1000000007 struct node { char s[105]; int num[105]; int v; }p[1005]; int ok(int p1,int p2,int l) { if(strlen(p[p1].s)<l+1||strlen(p[p2].s)<l+1) return 0; for(int i=0;i<=l;i++) if(p[p1].s [i]!=p[p2].s[i]) return 0; return 1; } int main() { int t,n,m,a,Case=1; char ch; int dir[10]={0,0,3,3,3,3,3,4,3,4}; char key[10][5]={{},{},{'a','b','c'},{'d','e','f'},{'g','h','i'}, {'j','k','l'},{'m','n','o'},{'p','q','r','s'},{'t','u','v'},{'w','x','y','z'}}; scanf("%d",&t); while(t--) { scanf("%d",&n); int i,j,k; for(i=0;i<n;i++) scanf("%s%d",p[i].s,&p[i].v); printf("Scenario #%d:\n",Case++); scanf("%d",&m); int count =0; for(i=0;i<m;i++) { count=-1; int vis[1005]; memset(vis,0,sizeof(vis)); while(scanf("%c",&ch)) { if(ch=='1') break; if(ch>'9'||ch<'2') continue; count++; a=ch-'0'; for(j=0;j<n;j++) { int flag=0; for(k=0;k<dir[a];k++) { if(p[j].s[count]==key[a][k]) { flag=1; break; } } if(!flag) vis[j]=1; } int w=-1,pos=-1,max=-1,num=0; for(j=0;j<n;j++) { if(!vis[j]) { if(pos==-1||ok(pos,j,count)) num+=p[j].v ; else num=p[j].v; if(num>max) { max=num; w=j; } pos=j; } } if(pos==-1) printf("MANUALLY\n"); else { for(k=0;k<=count;k++) printf("%c",p[w].s[k]); printf("\n"); } } printf("\n"); } printf("\n"); } return 0; }