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 成文