洛谷 P1481 魔族密码

题目背景

风之子刚走进他的考场,就……

花花:当当当当~~偶是魅力女皇——花花!!^^(华丽出场,礼炮,鲜花)

风之子:我呕……(杀死人的眼神)快说题目!否则……-_-###

题目描述

花花:……咦好冷我们现在要解决的是魔族的密码问题(自我陶醉:搞不好魔族里面还会有人用密码给我和菜虫写情书咧,哦活活,当然是给我的比较多拉*^_^*)。

魔族现在使用一种新型的密码系统。每一个密码都是一个给定的仅包含小写字母的英文单词表,每个单词至少包含 11 个字母,至多 7575 个字母。如果在一个由一个词或多个词组成的表中,除了最后一个以外,每个单词都被其后的一个单词所包含,即前一个单词是后一个单词的前缀,则称词表为一个词链。例如下面单词组成了一个词链:

  • i;
  • int;
  • integer。

但下面的单词不组成词链:

  • integer;
  • intern。

现在你要做的就是在一个给定的单词表中取出一些词,组成最长的词链,就是包含单词数最多的词链。将它的单词数统计出来,就得到密码了。

风之子:密码就是最长词链所包括的单词数阿……

输入格式

这些文件的格式是,第一行为单词表中的单词数 N(1≤N≤2000),下面每一行有一个单词,按字典顺序排列,中间也没有重复的单词。

输出格式

输出共一行,一个整数,表示密码。

输入输出样例

输入 #1

5
i
int
integer
intern
internet

输出 #1

4

解题思路

本题可以采用字典树来求解,对于如何求重复的过程只需要在输入字符串后插入的过程统计前面是否有以此字母结尾就可以了,通常用数组标记是否为结尾。

#include
int tire[20000][26], max = -1e9, id, cnt[20000];
char s[76];
void insert()//插入函数
{
	int i, p = 0, k = strlen(s), x, sum = 0;
	for (i = 0; i < k; i++)
	{
		x = s[i] - 'a';
		if (tire[p][x] == 0)
			tire[p][x] = ++id;
		if (cnt[p] == 1)//判断是否有以s[i]结尾的单词,有的话单词数量+1
			sum++;
		p = tire[p][x];
	}
	cnt[p] = 1;//插入的单词结尾做好标记
	if (max < sum + 1)//更新最大值
		max = sum + 1;
}
int main()
{
	int n, i;
	scanf("%d", &n);//输入单词个数
	while (n--)
	{
		scanf("%s", s);//输入单词
		insert();//进行插入
	}
	printf("%d", max);
	return 0;
}

你可能感兴趣的:(题组,学习)