题目链接:https://codeforces.com/contest/1675/problem/E
因为这里只有26个字母,所以对于每个字母,从左往右,如果k有剩余,那么就尽量将字母变成a,且将由这个字母变为a的过程全都打上标记(染色),下次再遇到这段区间的时候,可以直接过去且不用消耗k。
(这道题也可以用set去区间合并,不过写起来较麻烦,相当于有多段区间,判断新的字母应当放在哪道区间里)
#include <cmath>
#include <cstdio>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
inline int read(){
int t = 0,f = 1;
register char c = getchar();
while (c < 48 || c > 57) f = (c == '-') ? (-1) : (f),c = getchar();
while (c >= 48 && c <= 57) t = (t << 1) + (t << 3) + (c ^ 48),c = getchar();
return f * t;
}
inline int reads(char* s){
int t = 0;
register char c = getchar();
while (c < 'a' || c > 'z') c = getchar();
while (c >= 'a' && c <= 'z') s[++t] = c,c = getchar();
return t;
}
const int N = 2e5 + 10;
int T,n,k;
char inp[N + 1],s[N + 1];
bool used[27];
int main(){
T = read();
while (T--){
n = read(),k = read();
reads(s);
for (int i = 1;i <= n;i++) inp[i] = s[i];
memset(used,0,sizeof used);
for (int i = 1;i <= n;i++){
if (k <= 0) break;
while (k >= 1 && s[i] != 'a'){
if (!used[s[i] - 'a' - 1]) used[s[i] - 'a' - 1] = 1,--k;
cout<<char(s[i]-1)<<'\n';
s[i] = s[i] - 1;
}
}
for (int i = 1;i <= n;i++){
while (used[inp[i] - 'a' - 1]){
inp[i]--;
}
}
for (int i = 1;i <= n;i++) putchar(inp[i]);
putchar('\n');
}
return 0;
}