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;
}
原文地址:https://www.cnblogs.com/gtarcoder/p/4814970.html