hdu T9 ,poj1451

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

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

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

字典树+深搜。。

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

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;

}

你可能感兴趣的:(poj)