• poj_3283 trie树


    题目大意

        将一副牌进行编号,四种花色分别标记为'C'、'D'、'H'、'S',数值标记为'A'、'1'、'2'、'3'、'4'、'5'、'6'、'7'、'8'、'9'、'10'、'J'、'Q'、'K',则一张牌可以标记为 “数值+花色”,比如 7D, AH, 10S等。 
        给出N个牌的序列,每个序列视为一条链,每张牌视为链中的一个节点,为了方便存储,可以将具有相同后缀的链聚合在一起。求聚合之后的链中所有节点的个数。

    题目分析

        具有相同后缀的可以合并在一起,则等价于将每条链翻转之后,具有相同前缀的可以将前缀共享合并,这就是典型的trie结构。因此,需要将牌进行hash之后,获得索引,然后插入trie树中。 

      其中,翻转操作可以通过stack的push/pop来实现。
        为了求得总共的节点的数目,可以使用静态数组方式而不是指针方式来存储trie树。

    实现(c++)

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<string.h>
    #include<stack>
    using namespace std;
    #define MAX_CHILD_NUM 53
    char gSuit[4] = { 'C', 'D', 'H', 'S' };
    char gValue[4] = { 'A', 'J', 'Q', 'K' };
    int gValueHash[4] = { 0, 10, 11, 12 };
    struct Card{
    	int suit;
    	int value;
    };
    void CardHash(char* card, Card& car){
    	char suit, value;
    	if (strlen(card) == 3){
    		suit = card[2];
    		car.value = 9;
    	}
    	else{
    		suit = card[1];
    		value = card[0];
    		
    		if (value >= '2' && value <= '9'){
    			car.value = value - '0' - 1;
    		}
    		else{
    			for (int i = 0; i < 4; i++){
    				if (gValue[i] == value){
    					car.value = gValueHash[i];
    					break;
    				}
    			}
    		}
    	}
    	int i;
    	for (i = 0; i < 4; i++){
    		if (gSuit[i] == suit){
    			break;
    		}
    	}
    	car.suit = i;
    }
    
    struct TrieNode{
    	int count;
    	int childs[MAX_CHILD_NUM];
    	TrieNode(){
    		count = 0;
    		memset(childs, 0, sizeof(childs));
    	}
    };
    
    TrieNode gNodes[100000];
    int gIndex;
    
    void Insert(int root, stack<Card>& card_stack){
    	int node = root;
    	Card card;
    	while (! card_stack.empty()){
    		card = card_stack.top();
    		card_stack.pop();
    
    		int index = 13 * card.suit + card.value;
    		if (gNodes[node].childs[index] == 0){
    			gNodes[node].childs[index] = gIndex++;
    		}
    		node = gNodes[node].childs[index];
    		
    	}
    	gNodes[node].count++;
    }
    
    int main(){
    	int n, m;
    	char card[4];
    	stack<Card> card_stack;
    	int suit, value;
    	Card car;
    	while (scanf("%d", &n) != EOF){
    		if (n == 0){
    			break;
    		}
    		memset(gNodes, 0, sizeof(gNodes));
    		gIndex = 2;
    		while (n--){
    			scanf("%d", &m);
    			getchar();
    			for (int i = 0; i < m; i++){
    				for (int k = 0; k < 3; k++){
    					scanf("%c", card + k);
    				}
    				if (*(card + 1) == '0'){
    					*(card + 3) = 0;
    					getchar();
    				}
    				else{
    					*(card + 2) = 0;
    				}
    				CardHash(card, car);
    				//printf("card = %s
    ", card);
    				card_stack.push(car);
    			}
    			Insert(1, card_stack);
    		}
    		printf("%d
    ", gIndex - 2);
    	}
    	return 0;
    }
    
  • 相关阅读:
    二手房交易平台需求分析心得——字节移动小组
    结对编程之个人项目代码分析
    五月最新版 重装win10软件
    学习必备的——超级有用的网站!!!
    SQL中sa被禁用
    19 erp沙盘校赛
    temp
    Bootstrap 学习日志(二)
    Bootstrap 学习日志(一)
    关于Android上进行模拟登陆时的验证码问题
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4814970.html
Copyright © 2020-2023  润新知