题目描述
很多学校都监督考试,而使用成本也非常昂贵。当只监督一个考场时,每监视一分钟收费3金币;同时监视两个以上的考场,每监视一分钟收费4金币;当处于两个监考任务之间的空隙时,每分钟消耗1金币。也就是说,直到完成最后一个监考任务之前,都会持续消耗金币。
每个考场的考试开始时间和结束时间都不同。为简化表达,将时间简化为整数代表的时间单位,时间从0开始。
请你计算今天的监考任务能够收取多少金币。
输入描述
- 第一行一个整数 ( n ),表示今天的监考考场数量。
- 接下来 ( n ) 行,每行给出由空格分开的两个整数 ( a_i ) 和 ( b_i ),表示每个考场考试的开始时间 ( a_i ) 和结束时间 ( b_i )(闭区间),保证结束时间大于起始时间。
数据范围:
- ( 1 < n < 10000 )
- ( 0 < a_i, b_i <10^6 )
输出描述
一个整数,代表塔子哥今天监考所能赚取的金币。
用例输入
3
1 5
4 6
6 6
21
解题思路
- 时间线差分数组:
- 使用一个差分数组
task
来记录每个时间点的考场数量变化。 - 对于每个考场,增加开始时间的计数,减少结束时间+1的计数。
- 使用一个差分数组
- 遍历时间线:
- 从最早开始时间到最晚结束时间,遍历差分数组,计算每个时间点的考场数量。
- 根据考场数量计算费用:
- 0个考场:待机状态,每分钟消耗1金币。
- 1个考场:每分钟收费3金币。
- 2个及以上考场:每分钟收费4金币。
- 累加费用:将每个时间点的费用累加,得到总费用。
代码实现
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
int be = 1000000, en = -1000000;
vector<int> task(1000005, 0);
for (int i = 0; i < n; i++) {
int b, e;
cin >> b >> e;
task[b]++;
task[e + 1]--;
be = min(be, b);
en = max(en, e);
}
int res = 0;
int cur = 0; // 当前几个考场
for (int i = be; i <= en; i++) {
cur += task[i];
if (cur == 0) res++;
else if (cur == 1) res += 3;
else res += 4;
}
cout << res;
return 0;
}