Codeforces Round 787 (Div. 3)(E)

//脑抽了,一开始想的乱78糟

//贪心

E. Replace With the Previous, Minimizett

意:给一个字符串s , 操作: 选择一个在字符串中至少出现一次的字符。并在循环中按字母顺序将字符串中所有这样的字符替换为前一个字符。例如,将所有“c”替换为“b”或将所有“a”替换为“z”;给你一个整数k ,通过执行不超过k次的操作,找到字典序可能的最小字符串

思路:其实k至少是25就可以得到一串'a';

判断每一个字母变成'a'的最大步数ct;只要k>=ct,都可以变成'a';

直到遇到一个ct>k的字母s[i],此时操作k次不能变成'a',说明它不能跟前面k>=ct的字母一起操作;

k-=ma(前面能变成'a'的最大ct);在s[i]位上一定能把k全部减掉;即得到了一个区间[ct-k,ct]//[l,r]

此时s[i]位上已经变成字典序最小;判断后面的字母:1.ma>=ct 2.l<=ct<=r 其他情况无法操作

void solve()
{
	cin >> n >> k >> s;
	int ma = 0;
	int l=0, r=0;
	for (int i = 0; i < s.size(); i++)
	{
		int ct = s[i] - 'a';
		
		if(!r)
		{
		    if(k>=ct)
		        s[i] = 'a', ma = max(ma, ct);
		    else{
		        k-=ma,r=ct,l=ct-k;
		        s[i]='a'+l;
		    }
		}
		else
		{
		    if(ma>=ct)
		        s[i]='a';
		    else if(l<=ct&&ct<=r) 
		        s[i]='a'+l;
		}
	}
	cout << s << endl;
}

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值