题目链接:点击打开链接
题解思路:令len = n/2;题目要求我们操作次数正好m的最小字典序,那么就分两种情况1:str[i]==str[i+len],此时可以不操作,也可以操作两步,也就是使两个字母都变成另一个字母;
我们可以设一个左右边界l,r。你会发现当l==0时奇数项是取不到了,这是就是任意的str[i]==str[i+len]的情况,当然我们一开始肯定要保证l<=m<=r,如果str[i]已经是'a'了,这个时候可能是要变得,那就是m==r的情况,因为你要是不操作,r减小了而m不变那么m就超出范围了,另外是str[i]!='a'这时要保证m-2>=l。2:当str[i]!=str[i+len]时,那么当min(str[p],str[p+len]) == ‘a’时,此时要变成'a'只需要操作一次,但可能操作一次后接下来就操作不了了,这是就要保证(l!=1或m当前状态是奇数)且m!=r(不然m只减1而r减了2就要越界了),下面的情况都是类似的
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mx = 1e3+10;
int n,m;
char str[mx],ans[mx];
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
scanf("%s",str);
int l = n/2,r = n,len = n/2;
for(int i=0;i<len;i++)
if(str[i]==str[i+len]) l--;
if(!l&&(m&1)) { puts("Impossible"); continue; }
if(m<l||m>r) puts("Impossible");
else{
int p =0;
while(m){
if(str[p]==str[p+len]){
if(str[p]!='a'&&m>=l+2){
str[p] = str[p+len] = 'a';
m -= 2;
}
if(str[p]=='a'&&m==r){
str[p] = str[p+len] = 'b';
m -= 2;
}
r -= 2;
}else{
char ch = min(str[p],str[p+len]);
if(ch=='a'){
if((l!=1||(m&1))&&m<r){
str[p] = str[p+len] = 'a';
m--;
}else{
if(max(str[p],str[p+len])=='b') str[p] = str[p+len] = 'c';
else str[p] = str[p+len] = 'b';
m -= 2;
}
}else{
if((l!=1||!(m&1))&&m>l){
str[p] = str[p+len] = 'a';
m -= 2;
}else{
str[p] = str[p+len] = ch;
m--;
}
}
l--, r-=2;
}
p++;
}
puts(str);
}
}
return 0;
}