这两天都没怎么在状态,,希望做过这道题之后又能重新找到激情。。。^_^

感觉题目出的不错,,很现实的东西。。

题目大意:模拟手机输入法。。。

字典树+深搜。。

刚开始以为只在一个串上呢。。举个例子来说明。。

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;
}
posted on 2011-04-29 18:04  奋斗青春  阅读(562)  评论(0编辑  收藏  举报