蓝桥杯备赛-差分-推箱子
在一个高度为H的箱子前方,有一个长和高为N的障碍物。
障碍物的每一列存在一个连续的缺口,第i列的缺口从第l各单位到第h个单位(从底部由0开始数)。
现在请你清理出一条高度为H的通道,使得箱子可以直接推出去。
请输出最少需要清理的障碍物面积。
如下图为样例中的障碍物,长和高度均为5,箱子高度为2。(不需要考虑箱子会掉入某些坑中)
最少需要移除两个单位的障碍物可以造出一条高度为2的通道。
输入格式
输入第一行为两个正整数N和H,表示障碍物的尺寸和箱子的高度,1≤H≤N≤1000000。
接下来N行,每行包含两个整数li和hi,表示第i列缺口的范围,0≤li≤hi<N。
输出格式
输出一个数字表示答案。
输入样例
5 2
2 3
1 2
2 3
1 2
2 3
输出样例
2
通过率90%
障碍物高度为n,前缀和数组a和差分数组大小为n+1
前缀和ai表示第i行有几个空位置
依次读取每次的缺口,在差分数组上做标记,在利用数组之间的关系,更新前缀和数组
更新完,就从最底的一行开始遍历每一行障碍物,每次遍历计算h行的非空数+(h-a[i])即可
#include<stdio.h>
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
int main()
{
long long n, h;
cin >> n >> h;
vector<long long> a(n + 2, 0);//前缀和数组
vector<long long> d(n + 2, 0);//差分数组
long long l, r;
for (int i = 1; i <= n; i++) {
cin >> l >> r;
d[l + 1]++;
d[r + 2]--;
}
for (int i = 1; i <= n; i++) {
a[i] = a[i - 1] + d[i];
}
long long min = LLONG_MAX;
for (int i = 1; i <= n - h + 1; i++) {
long long count = 0;
for (int j = 0; j < h; j++) {
count += (n - a[i + j]);
}
if (count < min) {
min = count;
}
}
cout << min;
return 0;
}