[贪心] [字典序] CF254C Anagram
我们用桶
显然我们需要且仅需要将
然后是第二问。字典序最小,考虑贪心。我们从左往右遍历
-
* 如果能找到当前最小的满足 $c<S_i$ 的一类字符 $c$,则将 $S_i$ 换成 $c$。 * 如果不能,则判断当前字符是否必须操作,如果是则找到当前最小的一类字符 $c$,并将 $S_i$ 换成 $c$。否则不需操作。 -
正确性显然,复杂度
最后有个坑,就是这道题需要 freopen。。。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, P = 26;
int n, buc[P], ans, s[N], mp[P];
char a[N], b[N];
signed main(){
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
scanf("%s%s", a + 1, b + 1);
n = strlen(a + 1);
for(int i = 1; i <= n; ++i) ++buc[a[i] - 'A'], --buc[b[i] - 'A'];
for(int i = n; i >= 1; --i) s[i] = s[mp[a[i] - 'A']] + 1, mp[a[i] - 'A'] = i;
for(int i = 1; i <= n; ++i){
if(buc[a[i] - 'A'] > 0){
int id = -1, id2 = -1;
for(int j = P; ~j; --j)
if(buc[j] < 0){
id2 = j;
if(j < a[i] - 'A') id = j;
}
if(id == -1){
if(s[i] <= buc[a[i] - 'A']) {
++buc[id2], --buc[a[i] - 'A'], ++ans;
a[i] = char('A' + id2);
}
}
else{
++buc[id], --buc[a[i] - 'A'], ++ans;
a[i] = char('A' + id);
}
}
}
printf("%d\n%s", ans, a + 1);
return 0;
}