原题链接
1 题目
1.1 题目所需求出内容
对于本题,最终要求:一个合法方案
1.2 题目背景、允许、禁止与限制
背景:
现在有 nnn 个单词
允许:
重排字母表,排完之后将每个单词的 aaa 替换为当前字母表中的第一个单词,将每个单词的 bbb 替换为当前字母表中的第二个单词,以此类推...
给出 nnn 个不重复的数字 aia_iai ,第 iii 个表示希望单词 iii 按照重排字母表后“字典序”排序能够被排到第 aia_iai 个
求存不存在一种重排字母表的方案使得将所有单词替换完毕后能够按给定要求排序成功
1.3 题目数据范围与猜测
1≤n≤100,每个字符串长度≤100⟶O(n2×∣s∣)1 \le n \le 100, 每个字符串长度 \le 100\longrightarrow O(n^2 \times |s|)1≤n≤100,每个字符串长度≤100⟶O(n2×∣s∣)
1.4 一句话概括题意
现在有一些字符串
求一种字母表排列方案使得按该字母表对应的字典序排序后它们都能被排到期望位置上
2 题目破题推导
2.1 第一步:建模
因为题目要求字母表重排后单词按照 a1,a2,⋯ ,ana_1,a_2,\cdots,a_na1 ,a2 ,⋯,an 的顺序排列
那么就会得到一些约束条件:
考虑字典序的比较方式:找到第一位不同的字母并按照字母表的顺序排列
那么就代表 s[a1]s[a_1]s[a1 ] 与 s[a2]s[a_2]s[a2 ] 的第一位不同字符在字母表中的顺序应该是 s[a1]s[a_1]s[a1 ] 的那一位在先
现在就可以把字母当做图上的节点,将 <<< 的关系当做图上的边,也就是建一条 s[a1]对应位置字符→s[a2]对应位置字符s[a_1]对应位置字符 \rightarrow s[a_2]对应位置字符s[a1 ]对应位置字符→s[a2 ]对应位置字符 的有向边
2.2 第二步:分情况讨论
经过建模,这道问题已经变成了“能否给 262626 个英文字母排序,使得图中所有 u→vu\rightarrow vu→v 的边都在字母表中体现为 uuu 排在 vvv 前面?”
* 那么如果发现这张图上有环,说明出现 u→v→w→uu\rightarrow v \rightarrow w \rightarrow uu→v→w→u(或者更长),也就是 u<v,v<w但w<uu < v,v < w但w < uu<v,v<w但w<u
这样根本没法排
* 那么如果没环呢
说明存在这样的一个顺序
这个字母表的顺序中,不受影响的字母不变
其他的字母有一个映射的关系:
我们按拓扑序排序字母后得到序列ans ans1,ans2,⋯ ,ansnans_1,ans_2,\cdots,ans_nans1 ,ans2 ,⋯,ansn
将拓扑排序后的字母再进行一次正常排序(也就是没有改动之前的顺序),得到数组anssort
那么替换最终答案(用 answer 表示):answer[ansi]=anssortianswer[ans_i] = anssort_ianswer[ansi ]=anssorti
2.3 第三步:边界意识
考虑所有会导致合理字母表不存在的地方:
* 当两个单词 aaa 和 bbb 出现 ∣a∣<∣b∣且a是b的前缀,且a对应a数组要求位置ai>b对应a数组要求位置aj|a| < |b| 且 a是b的前缀,且a对应a数组要求位置a_i>b对应a数组要求位置a_j∣a∣<∣b∣且a是b的前缀,且a对应a数组要求位置ai >b对应a数组要求位置aj ,那么这种情况是不存在的,因为 ∣a∣<∣b∣同时a是b的前缀|a| < |b| 同时a是b的前缀∣a∣<∣b∣同时a是b的前缀,所以 aaa 无论怎么样都一定排在 bbb 前面(因为字典序是全部相同比长度)
* 当图上出现环(拓扑序遍历失败),则也不可能出现,就像刚刚2.2部分说的那样
* 当一个字符 aaa 需要变换位置(也就是被图包含),但是拓扑序没有遍历到,说明拓扑序中出现了问题,也不可能有正确方案
其他都可能出现正确方案
3 模型匹配
拓扑排序查看合法性
4 最终代码(禁止抄袭,仅用于参考)