题目大意
将一副牌进行编号,四种花色分别标记为'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; }