Bit Flipping(思维+贪心)

题目

原题链接


问题描述

给定一个由01所组成的字符串,总共要对其进行 K K K次操作,每次操作是从中选择一位,将除此位以外的其余位均进行翻转,问经过 k k k次操作可以得到的最大字典序的序列。


分析

1.对于一个从未选择过的位置,将进行 k k k次翻转,而每选择一个位置,就可以使其的翻转次数减一。
2.对于每个位置,只有进行奇数次翻转才有意义,偶数次翻转对结果无影响。

所以我们从高往低进行枚举,考虑这个位置本应该进行翻转的次数,以及是否需要进行调整(调整也就是对其分配一次操作);如果最后仍然有多余的操作,偶数次则随便置于一处即可,奇数次则分配给最低位的1,并将其置为 0 0 0

代码

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
#define fir(i, a, b) for (ll i = (a); i <= (b); i++)
#define rif(i, a, b) for (ll i = (a); i >= (b); i--)
const int N=2e5+5;
char a[N];
ll t,n,k,tmp,b[N];
int main(){
	cin>>t;
	while(t--){
		memset(b,0,sizeof b);
		cin>>n>>k;
		tmp=k;
		getchar();
		fir(i,1,n){
			cin>>a[i];
		}
		ll flag=k%2;
		fir(i,1,n){
			if(!tmp){
				if(flag){
					if(a[i]=='1')a[i]='0';
					else if(a[i]=='0')a[i]='1';
				}
			}
			else if(a[i]=='1'){
				if(flag){
					tmp--;
					b[i]++;
				}
			}
			else if(a[i]=='0'){
				if(!flag){
					tmp--;
					b[i]++;
				}
				a[i]='1';
			}
		}
		if(tmp){
			if(tmp%2){
				b[n]+=tmp;
				a[n]='0';
			}
			else{
				b[1]+=tmp;
			}
		}
		fir(i,1,n)cout<<(char)a[i];
		cout<<endl;
		fir(i,1,n){
			cout<<b[i]<<" ";
		}
		cout<<endl;
	}
	return 0;
}
/*
6
6 3
100001
6 4
100011
6 0
000000
6 1
111001
6 11
101100
6 12
001110


*/


*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值