CF1256D - Binary String Minimizing(贪心+提高级)
CF1256D - Binary String Minimizing(源地址自⇔CF1256D)
Problem

tag:
⇔贪心、⇔提高级(*1500)
题意:
对于给定的 \(01\) 序列,至多进行 \(k\) 次操作,使得最终结果的字典序最小。操作规则如下:
- 每次操作可以交换位于 \(i\) 和 \(i + 1\) 位置的元素。
思路:
个人感觉是评分虚高的一题。核心思路是,从前往后遍历,将遇到的 \(0\) 移动到最前面。分三种情况讨论:
- 还有操作余量,出现 \(1\) :记录数量 Num。
- 还有操作余量,出现 \(0\) :需要将其移动至所有 \(1\) 的前面。即操作 Num次。- 输出一个 \(0\) 。
 
- 没有操作余量,出现 \(0\) :此时只能将其移动至连续段 \(1\) 的中间位置,可以唯一确定这个位置。
- 输出 Num - k + Used个前置 \(1\) ,一个 \(0\) ,k - Used个后置 \(1\) 。
- 直接输出剩下的全部内容。
 
- 输出 
要注意,对于情况2,若操作完所有的 \(0\) 之后仍有操作余量,则需要将剩下 Num 个 \(1\) 全部输出。
AC代码(伪代码):
cin >> n >> m;
cin >> S;
int len = sz(S) - 1;
FOR(i, 0, len) {
	if(S[i] == '1') {
		num ++;
	}else if(S[i] == '0' && u + num <= m) {
		u += num;
		cout << 0;
	}else if(S[i] == '0' && u + num > m) {
		FOR(j, 1, num - m + u) cout << 1;
		cout << 0;
		FOR(j, 1, m - u) cout << 1;
		FOR(j, i + 1, len) cout << S[j];
		cout << EE;
		return;
	}
}
FOR(i, 1, num) cout << 1;
cout << EE;
错误次数
无
文 / WIDA
2021.12.18 成文
首发于WIDA个人博客,仅供学习讨论
更新日记:
2021.12.18 成文
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号