题目大意
题目链接,给定 (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
", ans);
return 0;
}