酷暑一夏1

不忘初心,方得始终


Vijos1415 魔族密码 题解

题目核心部分

魔族现在使用一种新型的密码系统。每一个密码都是一个给定的仅包含小写字母的英文单词表,每个单词至少包含1个字母,至多75个字母。如果在一个由一个词或多个词组成的表中,除了最后一个以外,每个单词都被其后的一个单词所包含,即前一个单词是后一个单词的前缀,则称词表为一个词链。例如下面单词组成了一个词链:
i
int
integer
但下面的单词不组成词链:
integer
intern
现在你要做的就是在一个给定的单词表中取出一些词,组成最长的词链,就是包含单词数最多的词链。将它的单词数统计出来,就得到密码了。
风之子:密码就是最长词链所包括的单词数阿……
花花:活活活,还有,这些文件的格式是,第一行为单词表中的单词数N(1<=N<=2000),下面每一行有一个单词,按字典顺序排列,中间也没有重复的单词咧!!你要提交的文件中只要在第一行输出密码就行啦^^

题解

Trie,在插入的时候就可以统计了,求一条isend数量最大的链$^{*}$。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<cstdio>
#include<algorithm>
const int MAXL=75+5;
const int MAXT=26+5;
struct Trie{Trie* next[MAXT];bool isend;};
int ans;char inp[MAXL];
void InitNode(Trie* node)
{
for(int i=0;i<MAXT;i++)
node->next[i]=NULL;
node->isend=0;
return;
}
void Insert(Trie* root,char* str)
{
int passes=0;
while(*str!='\0')
{
if(root->isend) passes++;
if(root->next[*str-'a']==NULL)
{
Trie* tmp=new Trie;
InitNode(tmp);
root->next[*str-'a']=tmp;
}
root=root->next[*str-'a'];
str++;
}
root->isend=1;
passes++;
if(passes>ans) ans=passes;
return;
}
int main()
{
int n;
scanf("%d",&n);
Trie* root=new Trie;
InitNode(root);
for(int i=1;i<=n;i++)
{
scanf("%s",inp);
Insert(root,inp);
}
printf("%d",ans);
return 0;
}

附注

$^{*}$文中链的表达可能不是很准确,详见代码Insert函数。

最近的文章

Vijos1022 Victoria的舞会2 题解

题目Victoria是一位颇有成就的艺术家,他因油画作品《我爱北京天安门》闻名于世界。现在,他为了报答帮助他的同行们,准备开一个舞会。Victoria准备邀请n个已经确定的人,可是问题来了:这n个人每一个人都有一个小花名册,名册里面写着他所愿意交流的人的名字。比如说在A的人名单里写了B,那么表示A愿 …

于  Victoria的舞会, Vijos 继续阅读
更早的文章

Vijos1203 CoVH之华丽的IP伪装 题解

题目核心部分(没用的背景已省略,挺有趣的可以去看原题)如果我的推理没有错的话, 我们把访问过Vijos的IP地址调查一下, 找出当时它和哪些IP联络过, 筛选出向Vijos投过包的IP. 底下只考虑向Vijos投过包的IP, 对于两个直接联络过的IP, 他们发送的所有包的大小相加, 作为联络代价. …

于  CoVH系列, Vijos 继续阅读