POJ 1451(0ms)(dnf)(树的灵活建立)

翻译:http://blog.csdn.net/woniupengpeng/article/details/53445073


/*
	先建立一棵有26个节点的树,再建一个收集结果的结果集,然后用dnf去搜,与结果集相匹配的满足要求的就更新结果集,最后输出结果集就好了; 
*/ 
#include <iostream>
#include <fstream>
#include <cstring>
#include <malloc.h>
using namespace std;
typedef struct tree{
	int count;
	int rank;
	char father[100];
	char key[100];
	tree *next[26];
	tree(){
		count = 0;
		rank = 0;
		for(int i=0; i<26; ++i)
			next[i] = NULL;
		for(int i=0; i<105; ++i){		
			father[i] = '\0';
			key[i] = 0;
		}
	}	
} tree;
void dfs(tree * root);
tree root;			//根节点 
char str[105];		//输入字符串的容器 
int len;			//记录字符串的长度 
char res[100][100]; //记录结果的单词 
int res_i[100];  //比较结果的概率 
char str_arr[] = "22233344455566677778889999";
int main(){	
	int row,num,flag,max,sum,now;
	int input;		
	tree *temp;
	scanf("%d",&sum);	
	for(int sum1=1; sum1<=sum; ++sum1){
		printf("Scenario #%d:\n",sum1);
		//初始化根节点 		
		root.count = 0;
		for(int i=0; i<26; ++i){
			root.next[i] = NULL;
		}
		//初始化根节点END
		//接收输入
		scanf("%d",&row);		
		while(row--){			
			temp = &root;
			scanf("%s",str);
			scanf("%d",&num);
			len = strlen(str);
			for(int i=0; i<len; ++i){
				int index = str[i] - 97;
					if(temp->next[index] == NULL){				
					tree * t1 = new tree();
					temp->next[index] = t1;				
				}
				//更新结构体里的各种信息; 
				temp->next[index]->count += num;
				temp->next[index]->rank = i+1;								
				strcpy(temp->next[index]->father, str);
				temp->next[index]->father[i+1] = '\0';				
				strcpy(temp->next[index]->key, temp->key);
				temp->next[index]->key[i] = str_arr[str[i]-97];
				temp->next[index]->key[i+1] = '\0';
				//让更新数据的节点,指向下一个节点; 
				temp = temp->next[index];
			}			
		}		
		//测试阶段
		scanf("%d",&row);
		for(int i=0; i<row; ++i){			
			scanf("%s",str);		
			len = strlen(str);
			for(int j=0; j<len; ++j){
				res_i[j] = 0;
				for(int k=0; k<len; ++k){
					res[j][k] = '\0';
				}
			}
			str[len-1] = '\0';
			dfs( &root);
			for(int i=0; i<len-1; ++i){
				if(strlen(res[i]) !=0 ){					
					printf("%s\n",res[i]);
				}else
					printf("MANUALLY\n");
			}
			printf("\n");
		}
		printf("\n");
	}
}
void dfs(tree *node){	
	char str1[100];
	int i;
	for(i=0; i<node->rank+1; ++i){
		str1[i] = str[i];
	}
	str1[i] = '\0';
	for(i=0; i<26; ++i){		
		if(node->next[i] != NULL){
			//只有九宫格数字匹配和单词的概率大于结果集里的就可以更新; 
			if( (res_i[node->next[i]->rank-1] < node->next[i]->count) && strcmp(str1, node->next[i]->key)==0 ){				
				res_i[node->next[i]->rank-1] = node->next[i]->count;
				strcpy(res[node->next[i]->rank-1],node->next[i]->father);
			}
			if(node->next[i]->rank+1 < len)
				dfs(node->next[i]);
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值