题目描述
Aya 在网校共有两名助教,她们的网名分别为某 E 和 L 队。
Aya 热衷于开盒。他对两名助教使用了盒武器,得知某 E 的真实姓名为一个字符串 ss,L 队的真实姓名为一个字符串 tt。两个人的名字均只包含英文小写字母。
Aya 确信实力和姓名的字典序有关,姓名字典序越靠前,实力越强。
但是事实上,L 队的实力严格强于某 E。所以,你需要重新确定 2626 个英文小写字母的大小顺序,以保证 Aya 得到的结果与事实相符。
也就是说,请你重新定义 2626 个字母之间的大小关系,使得按照你新定义的大小关系比较 s,ts,t 两字符串的字典序时,满足 t < st<s。
字符串 tt 的字典序小于 ss 的字典序当且仅当满足如下两个条件之一:
- tt 是 ss 的一个前缀;
- 存在一个位置 j \leq \min(|s|, |t|)j≤min(∣s∣,∣t∣),使得对 1 \leq i < j1≤i<j 都有 s_i = t_isi=ti 且 t_j < s_jtj<sj。其中两字符相比较的小于号是你重新定义的小于关系。
输入格式
输入的第一行为一个字符串 ss。
输入的第二行为一个字符串 tt。
输出格式
输出一行一个字符串,长度为 2626,\texttt{a} \sim \texttt {z}a∼z 这些字符在你的输出中均应恰好出现一次,以表示字母之间新定义的大小关系。
在输出中靠前位置的字母小于在输出中靠后位置的字母。
答案可能有多种,你只需要给出任意一组。
输入输出样例
输入 #1复制
b a
输出 #1复制
abcdefghijklmnopqrstuvwxyz
说明/提示
数据规模与约定
- 对于 30\%30% 的数据,|s|=|t|=1∣s∣=∣t∣=1;
- 对于 60\%60% 的数据,|s|=|t|∣s∣=∣t∣;
- 对于 100\%100% 的数据,1 \le |s|,|t| \le 10^61≤∣s∣,∣t∣≤106,且 s \neq ts=t。
数据保证存在一种方式,使得字典序上 t<st<s。
题目大意
给定两个字符串 ss 和 tt。重新定义 2626 个字母之间的大小关系,使得按照新定义的大小关系,tt 的字典序小于 ss 的字典序。
解析
提供两种做法。第一种比较容易想到,但是码量较大。第二种码量极短,但是可能有点难想到。
第一种做法如下:
我们注意到 t < st<s 的两个条件为「tt 是 ss 的一个前缀」或「存在一个位置 j \leq \min(|s|, |t|)j≤min(∣s∣,∣t∣),使得对 1 \leq i < j1≤i<j 都有 s_i = t_isi=ti 且 t_j < s_jtj<sj」。自然而然地,t > st>s 的两个条件为「ss 是 tt 的一个前缀」或「存在一个位置 j \leq \min(|s|, |t|)j≤min(∣s∣,∣t∣),使得对 1 \leq i < j1≤i<j 都有 s_i = t_isi=ti 且 t_j > s_jtj>sj」。
由于题目保证了 s \neq ts=t,因此 tt 与 ss 的关系只有以上四种可能。
考虑 t > st>s 的两个条件。对第一个条件,显然,我们不可能通过调整字母之间的大小关系使得 t < st<s,且题目保证了数据一定有解,所以这种情况一定不存在。
现在我们需要下手的情况只有一个了,即「存在一个位置 j \leq \min(|s|, |t|)j≤min(∣s∣,∣t∣),使得对 1 \leq i < j1≤i<j 都有 s_i = t_isi=ti 且 t_j > s_jtj>sj」。
不难发现,这种情况下,我们只需要修改 t _ jtj 与 s _ jsj 的大小关系,使之满足 t _ j < s _ jtj<sj 即可。因此,我们对这两位单独处理,其余的按照任意顺序输出即可。
以下为此做法的核心代码:
scanf("%s%s", s, t);
lenS = strlen(s);
lenT = strlen(t);
int ptr = 0, minLength = min(lenS, lenT);
while (ptr < minLength) {
if (s[ptr] != t[ptr])
break;
++ptr;
}
if (ptr == minLength) {
for (int i = 'a'; i <= 'z'; ++i) {
printf("%c", i);
}
} else {
char a = t[ptr], b = s[ptr];
printf("%c%c", a, b);
for (int i = 'a'; i <= 'z'; ++i) {
if (i != a && i != b)
printf("%c", i);
}
}
第二种做法如下:
由第一种做法,我们知道,如果 t > st>s,我们只需要修改「存在一个位置 j \leq \min(|s|, |t|)j≤min(∣s∣,∣t∣),使得对 1 \leq i < j1≤i<j 都有 s_i = t_isi=ti 且 t_j > s_jtj>sj」条件下 s _ jsj 与 t _ jtj 的关系即可。
我们考虑,如果我们将整个字母表的大小关系反转,即 \texttt{z} < \texttt{y} < \cdots < \texttt{b} < \texttt{a}z<y<⋯<b<a,那么无论 s _ jsj 与 t _ jtj 是哪个字母,只要原来 s _ j < t _ jsj<tj,那么在反转后的字母表中,t _ jtj 一定小于 s _ jsj。由此,我们即可保证 t < st<s。
所以这一种做法的代码量少得可怕,核心代码如下:
string s, t;
cin >> s >> t;
if (s > t) cout << "abcdefghijklmnopqrstuvwxyz" << endl;
else cout << "zyxwvutsrqponmlkjihgfedcba" << endl;