CF254C Anagram
题目描述
如果我们能够重新排列字符串 x x x 中的字母,从而得到与字符串 y y y 完全相同的字符串,那么字符串 x x x 就是字符串 y y y 的同字母异序词。例如,字符串 “DOG” 和 “GOD” 是同字母异序词,字符串 “BABA” 和 “AABB” 也是同字母异序词,但字符串 “ABBAC” 和 “CAABA” 不是。
给你两个长度相同且由大写英文字母组成的字符串 s s s 和 t t t 。你需要从字符串 s s s 得到字符串 t t t 的一个同字母异序词。你被允许执行替换操作:每次操作是将字符串 s s s 中的某个字符替换为任意其他字符。以最少的替换操作次数得到字符串 t t t 的一个同字母异序词。如果你能以最少的操作次数得到字符串 t t t 的多个同字母异序词,那么请得到字典序最小的那个。
字符串的字典序就是我们熟悉的 “字典” 顺序。形式上,如果对于某个 k k k( 1 ≤ k ≤ n 1 \leq k \leq n 1≤k≤n),有 p 1 = q 1 p_{1}=q_{1} p1=q1, p 2 = q 2 p_{2}=q_{2} p2=q2,……, p k − 1 = q k − 1 p_{k - 1}=q_{k - 1} pk−1=qk−1, p k < q k p_{k} < q_{k} pk<qk,那么长度为 n n n 的字符串 p p p 在字典序上小于长度相同的字符串 q q q 。这里字符串中的字符从 1 开始编号。字符串中的字符按照字母顺序进行比较。
输入格式
输入由两行组成。第一行包含字符串 s s s ,第二行包含字符串 t t t 。这两个字符串长度相同(长度范围是从 1 到 1 0 5 10^{5} 105 个字符)且都由大写英文字母组成。
输出格式
在第一行输出 z z z —— 从字符串 s s s 得到字符串 t t t 的一个同字母异序词所需的最少替换操作次数。在第二行输出在 z z z 次操作下能够得到的字典序最小的同字母异序词。
输入输出样例 #1
输入 #1
CDBABC
ADCABD
输出 #1
2
ADBADC
说明/提示
第二个样例中,有八个字符串 t t t 的同字母异序词可以通过恰好替换字符串 s s s 中的两个字母得到,它们分别是:“ADBADC”、“ADDABC”、“CDAABD”、“CDBAAD”、“CDBADA”、“CDDABA”、“DDAABC”、“DDBAAC” 。这些同字母异序词按字典序列出。字典序最小的同字母异序词是 “ADBADC” 。
题解
题目理解
本题的核心任务是将字符串 s s s 通过最少的字符替换操作,转换为字符串 $ t $ 的变位词。如果存在多个最少操作次数的结果,要输出字典序最小的那个。
题目分析
我们可以很快得出
a
n
s
=
∑
i
=
1
n
∣
a
i
−
b
i
∣
ans = \sum_{i=1}^{n} |a_i - b_i|
ans=∑i=1n∣ai−bi∣ 的最小步骤为
a
n
s
/
2
ans / 2
ans/2。
然后我们可以通过枚举
S
S
S,并找字母来替代他,来求最小的字典序字符串。
Code
#include <bits/stdc++.h>
using namespace std;
string A, B;
int a[30], b[30];
int cnt1[30], cnt2[30];
void read()
{
cin >> A;
cin >> B;
}
void solve()
{
for (int i = 0; i < A.size(); i++)
{
a[A[i] - 'A' + 1]++;
}
for (int i = 0; i < B.size(); i++)
{
b[B[i] - 'A' + 1]++;
}
int ans = 0;
for (int i = 1; i <= 26; i++)
{
int num = abs(a[i] - b[i]);
ans += num;
if (a[i] >= b[i])
{
cnt1[i] += num;
}
else
{
cnt2[i] += num;
}
}
cout << ans / 2 << endl;
for (int i = 0; i < A.size(); i++)
{
a[A[i] - 'A' + 1]--;
if (cnt1[A[i] - 'A' + 1])
{
for (int j = 1; j <= 26; j++)
{
if (j >= A[i] - 'A' + 1 && a[A[i] - 'A' + 1] >= cnt1[A[i] - 'A' + 1])
{
break;
}
if (cnt2[j])
{
cnt1[A[i] - 'A' + 1]--;
cnt2[j]--;
A[i] = char('A' + j - 1);
break;
}
}
}
}
cout << A << endl;
}
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
read();
solve();
return 0;
}