不同的缩写
不同的缩写
题目描述
你在写一款 Galgame 的剧情(的代码)。
在这个游戏中一共有 n 个角色。你需要编写一些关于这些角色的对话内容。然而,在写这些对话内容之前,都要写一段关于角色信息的代码,就像这样:
Character("Alex", color = "#FFFC3A")
你觉得这样好麻烦。你决定把它简化一下。你打算用角色名字的一个非空子序列(可以不连续)来作为它的简称。
当然,不同的角色要用不同的字符串作为简称,否则你就变量重名了。
你想确定一个简称的分配方案使得所有角色中最长的简称尽量短,这样你打起代码就会方便一些。
输入格式
从文件 diff.in
中读入数据。
第一行一个正整数 nnn 。
接下来 nnn 行,每行一个由小写字母组成的字符串,代表一个角色的名字。
不同的角色可能会有相同的名字。
输出格式
输出到文件 diff.out
中。
如果不存在一种分配简称的方案满足条件,输出 −1
。
否则第一行输出一个正整数,表示最长的简称的最小长度。
接下来 nnn 行每行一个字符串,按顺序表示每个角色的简称。
若有多种方案满足条件,那么你可以输出任意一种。
样例
样例输入
11
night
nealchen
beimingyouyu
echo
rankinf
dntcrybecthlev
lagoon
cyc
alphagem
leehwincing
clin
样例输出
1
g
a
m
e
r
b
o
y
l
w
c
数据范围与提示
保证 n≤300n \le 300n≤300 ,每个名字的长度不超过 300300300 。
Subtask 1(30 pts) : n≤4n \le 4n≤4
Subtask 2(30 pts) : n≥100n \ge 100n≥100 , 串长和串的内容在题目范围内均匀随机。
即串长在 [1,300][1,300][1,300] 内随机,串的每一位在 aaa 到 zzz 之间随机。
Subtask 3(40 pts): 无特殊限制
solution
假设我们已经知道了每个串的所有子序列,那么把子序列看成点,和串跑匹配即可。
那么需要找出每一个串的所有子序列(或者n个,n个已经足够)。
假设我们现在求出的一个串的前i个字符的所有子序列
我们考虑加入i+1个字符,对于每一个字母,记一个指针,表示上一次这个指针之前的串后面加过这个字母了。
这样就不用判重了。
注意映射比较繁杂,我用了trie树实现。