poj 1451(Trie)

题意:就是让你模拟手机输入单词。具体就是给你一些单词,以及该单词被使用的频数,这个频数也是该单词前缀的使用频数,当然不同的单词有可能有相同的前缀,那么这个相同的前缀的使用频数就是这两个单词使用频数之和,以此类推。然后再给你一些数字串,让你针对该数字串的每一个前缀输出它的最有可能对应的单词(即频数最大的字符串)。


解题思路:这道题目比我想象中的简单,直接dfs去搜,因为每个键的字母个数不超过5,所以不会TLE。。。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

struct node
{
	struct node *next[26];
	int p;
	node()
	{
		p = 0;
		for(int i = 0; i < 26; i++)
			next[i] = NULL;
	}
};
int n,pro;
char s[100],keyboard[10][5]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
char ans[100],tmp[100];

void add(char *str,int cnt,node *root)
{
	node *t = root;
	for(int i = 0; str[i] != 0; i++)
	{
		if(t->next[str[i]-'a'] == NULL)
		{
			t->next[str[i]-'a'] = new node();
		}
		t = t->next[str[i]-'a'];
		t->p += cnt;
	}
}

void dfs(int x,int pos,node *r)
{
	int num = s[pos] - '0';
	int len = strlen(keyboard[num]);
	for(int i = 0; i < len; i++)
	{
		int t = keyboard[num][i] - 'a';
		if(r->next[t] == NULL) continue;
		else tmp[pos] = keyboard[num][i];
		if(pos == x)
		{
			if(pro < r->next[t]->p)
			{
				pro = r->next[t]->p;
				strcpy(ans,tmp);
			}
		}
		else dfs(x,pos+1,r->next[t]);
	}
}

int main()
{
	int t,p,cas = 1;
	node *root;
	scanf("%d",&t);
	while(t--)
	{
		root = new node();
		scanf("%d",&n);
		for(int i = 1; i <= n; i++)
		{
			getchar();
			scanf("%s %d",s,&p);
			add(s,p,root);
		}
		printf("Scenario #%d:\n", cas++);
		scanf("%d",&n);
		for(int i = 1; i <= n; i++)
		{
			getchar();
			scanf("%s",s);
			int len = strlen(s);
			for(int j = 0; j < len-1; j++)
			{
				memset(tmp,0,sizeof(tmp));
				pro = 0;
				dfs(j,0,root);
				if(pro == 0)
					printf("MANUALLY\n\n");
				else printf("%s\n\n",ans);
			}
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值