B. Bit Flipping_二进制贪心

B. Bit Flipping

题目大意:

对一个长度为n的01串,可以进行m次整串翻转,每一次翻转时可以指定任意一个位置使其不变。现在要求出m次操作后字典序最大的一个串,并且输出每个位置被指定了几次。

思路和代码:

这应该是这一场里最简单的一题了8

首先,全局考虑一下可以发现,如果没有指定不变操作那么每一位都要被翻转m次。若指定i位k次,则i位翻转m-k次。我们要的是字典序最大,那么就可以从左往右一位一位考虑,每次尽可能使该位变成1。

走完后若操作数还有剩下,则尽量使得剩下的操作无效化。就是剩余操作数中的最大偶数次指定操作放到我们已经操作过的地方。

若还有剩余则改变第n位(这样改变最小)

void solve(){
	cin >> n >> m ;
	string s ;
	cin >> s ;
	s = " " + s ;
	vct<bool> ans(n + 1 , 0) ;
	vct<int > tms(n + 1 , 0) ;
	
	int num = m ;
	
	rep(i , 1 , n){
		bool now ;
		if(s[i] == '1' && m % 2 == 0 || s[i] == '0' && m % 2) ans[i] = now = 1 ;
		else now = 0 ;
		if(now) continue ;
		if(num < 1) continue ;
		num -- ;
		ans[i] = 1 ;
		tms[i] ++ ;
	}
	if(num > 0){
		rep(i , 1 , n){
			if(tms[i] > 0){
				tms[i] += num / 2 * 2 ;
				num %= 2 ;
				break ;
			}
		}
		if(num > 0){
			tms[n] += num ;
			if((m - tms[n]) & 1) ans[n] = s[n] == '1' ? 0 : 1 ;
			else ans[n] = s[n] - '0' ;
		}
		
	}
	rep(i , 1 , n) cout << ans[i] ; cout << "\n" ;
	rep(i , 1 , n) cout << tms[i] << " " ; cout << "\n" ;
}//code_by_tyrii 

小结:

比较简单的贪心

posted @ 2022-04-19 14:11  tyrii  阅读(154)  评论(0)    收藏  举报