专栏文章
题解:P12676 相等排列
P12676题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mip4vd0u
- 此快照首次捕获于
- 2025/12/03 06:12 3 个月前
- 此快照最后确认于
- 2025/12/03 06:12 3 个月前
思路
题目的目标是将分散的
1 尽可能合并成连续块,最小化最终块数。令 表示位置 和 两个 1 之间的连续 0 数量。当 时,优先填补 比 更优(同样操作次数能合并更多块)提取所有
1 的位置索引,统计相邻 1 间的 0 数量
然后按间隙大小升序排序,接着用操作数 优先填补小间隙代码实现
CPP#include <bits/stdc++.h>
using namespace std;
int main() {
int n, k;
scanf("%d%d", &n, &k);
vector<int> ones; // 存储所有 '1' 的位置索引
// 读取序列并记录 '1' 的位置
for (int i = 0; i < n; ++i) {
char c;
scanf(" %c", &c);
if (c == '1') ones.push_back(i);
}
// 特判:无 '1' 直接结束
if (ones.empty()) {
printf("0\n");
return 0;
}
// 计算初始块数(连续 '1' 视为单块)
int blocks = 1;
for (int i = 1; i < ones.size(); ++i) {
if (ones[i] != ones[i-1] + 1) blocks++;
}
// 提取块间间隙(忽略块内间隙)
vector<int> gaps;
int prev_end = ones[0]; // 当前块末尾位置
for (int i = 1; i < ones.size(); ++i) {
if (ones[i] != ones[i-1] + 1) { // 发现新块
int gap = ones[i] - prev_end - 1; // 计算间隙
if (gap > 0) gaps.push_back(gap);
prev_end = ones[i]; // 更新块尾
} else {
prev_end = ones[i]; // 同一块内移动
}
}
sort(gaps.begin(), gaps.end()); // 按间隙升序排序
// 贪心填补:优先消耗小间隙
int merged_blocks = 0;
for (int g : gaps) {
if (k >= g) {
k -= g;
merged_blocks++; // 每填一隙减少一个块
} else break;
}
// 输出:初始块数 - 成功合并数
printf("%d\n", blocks - merged_blocks);
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...