这两天都没怎么在状态,,希望做过这道题之后又能重新找到激情。。。^_^
感觉题目出的不错,,很现实的东西。。
题目大意:模拟手机输入法。。。
字典树+深搜。。
刚开始以为只在一个串上呢。。举个例子来说明。。
3
ac4
ab3
bp 5
271
如果按原来的想法会输出:
a
MANUALLY
但是后来一想,这明显的不符合手机上显示的。。
再想想感觉需要把所有的状态遍历一遍,,那就用深搜吧。。在搜最长的同时,那所有的都记录下来,,对于一行输入只需要搜一遍。。
代码:
# include<stdio.h> # include<string.h> # include<stdlib.h> # define PI 110 # define MAX 26 struct Trie{ int num; struct Trie *next[MAX]; }; int ans,dir[11]={0,0,0,3,6,9,12,15,19,22,26},len,k,max[PI];//记录手机上的每个数字所表示的字母 char st[PI],map[PI][PI],adj[PI]; Trie *NewTrie() { int i; Trie *temp= new Trie; temp->num=1; for(i=0;i<MAX;i++) temp->next[i]=NULL; return temp; }//初始化。。 void Insert(Trie *p,char s[]) { int i,len1; Trie *temp=p; len1=strlen(s); for(i=0;i<len1;i++) { if(temp->next[s[i]-'a']==NULL) {temp->next[s[i]-'a']=NewTrie();temp->next[s[i]-'a']->num+=(ans-1);} else temp->next[s[i]-'a']->num+=ans; temp=temp->next[s[i]-'a']; } }//插入 void updata(Trie *p,int step) { Trie *temp=p; int begin,end,j; begin=dir[st[step]-'0']; end=dir[st[step]-'0'+1]; for(j=begin;j<end;j++) { if(temp->next[j]==NULL) continue; k++; adj[k]=j+'a'; if(temp->next[j]->num > max[step]) { max[step] = temp->next[j]->num; adj[k+1]=0; strcpy(map[step],adj); } if(step!=len-1) updata(temp->next[j],step+1); k--; } }//深搜一遍 int main() { Trie *p; int i,j,n,m,ncase,t; char str[105]; scanf("%d",&ncase); for(t=1;t<=ncase;t++) { scanf("%d",&n); p=NewTrie(); while(n--) { scanf("%s %d",str,&ans); Insert(p,str); } scanf("%d",&m); printf("Scenario #%d:\n",t); while(m--) { scanf("%s",st); len=strlen(st); len--; k=-1; memset(max,-1,sizeof(max)); updata(p,0); for(i=0;i<len;i++) { if(max[i]!=-1) printf("%s\n",map[i]); else break; } for(j=i;j<len;j++) printf("MANUALLY\n"); printf("\n"); } printf("\n"); } return 0; }