hdu 5903 - 模拟

题目链接:点击打开链接


题解思路:令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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值