专栏文章
题解:P12350 「HCOI-R2」光影
P12350题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mipf7dtm
- 此快照首次捕获于
- 2025/12/03 11:01 3 个月前
- 此快照最后确认于
- 2025/12/03 11:01 3 个月前
思路
大意:为了将尽可能多的
令 表示 与 (两个
首先,将所有
其次,计算每一个 ,排序。 最后,照题意,从小到大删除
1(分散的)合并成尽可能少的“块”。令 表示 与 (两个
1)之间所有 0 的个数。如果 ,那么删除区间 会比删除 要优。首先,将所有
1 的位置找出来,将索引放入 Lkd 中。其次,计算每一个 ,排序。 最后,照题意,从小到大删除
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);
}
if (ones.empty()) { // 没有 '1' 的情况
printf("0\n");
return 0;
}
// 计算初始块数:连续的 '1' 视为一个块
int initial_ones = 1;
for (int i = 1; i < ones.size(); ++i) {
if (ones[i] != ones[i-1] + 1) initial_ones++;
}
// 计算相邻块之间的间隙
vector<int> gaps;
int prev_end = ones[0]; // 前一个块的最后一个 '1' 的位置
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 merge_cnt = 0;
for (int g : gaps) {
if (k >= g) {
k -= g;
merge_cnt++;
} else break;
}
printf("%d\n", initial_ones - merge_cnt);
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...