[trie树] hihocoder 1107 Shortest Proper Prefix

题目大意

题目链接,给定 \(n\) 个字符串,问有多少个前缀是 shortest proper prefix。数据量较小。

算法思路

shortest proper prefix 根据题目中解释为前缀出现过不超过5次,且该前缀所有更短的前缀出现过多于5次。建立一颗trie树,维护每个节点所表示前缀的单词数。

算法代码


#include <stdio.h>
#include <string.h>
using namespace std;

struct node
{
	node* child[26];   // 'a' ... 'z' child pointer
	node* parent;      // parent pointer, root->parent=NULL

	int freq;

	node() {
		freq = 0;
		memset(child, 0, sizeof(child));
		parent = NULL;
	}
};

char buf[2000005];
int len;
node *root;

void insert(node* p, int k)        // insert string
{
	if (p == NULL || k == len)
		return;
	p->freq++;
	
	if (p->child[buf[k] - 'a'] == NULL) {
		p->child[buf[k] - 'a'] = new node();
		p->child[buf[k] - 'a']->parent = p;
	}
	insert(p->child[buf[k] - 'a'], k + 1);
}

void del(node *p)          // delete all trie node
{
	if (p == NULL)
		return;
	for (int i = 0; i < 26; i++) {
		if (p->child[i] != NULL)
			del(p->child[i]);
		p->child[i] = NULL;
	}
	delete p;
	p = NULL;
}

int tri(node *p)
{

	if (p->parent != NULL) {
		if (p->freq <= 5 && p->parent->freq>5)        // shortest proper prefix!
			return 1;
	}

	int ans = 0;
	for (int i = 0; i < 26; i++) {
		if (p->child[i] != NULL)
			ans += tri(p->child[i]);
	}
	return ans;
}

int main()
{
	int n;
	scanf("%d", &n);
	
	root = new node();
	while (n--) {
		scanf("%s", buf);
		len = strlen(buf);

		insert(root, 0);
	}

	int ans = tri(root);
	del(root);

	printf("%d\n", ans);
	return 0;
}

posted @ 2016-05-02 02:48  小小的港湾  阅读(175)  评论(0编辑  收藏  举报