#P7913. [CSP-S 2021] 廊桥分配
[CSP-S 2021] 廊桥分配
题目描述
当一架飞机抵达机场时,可以停靠在航站楼旁的廊桥,也可以停靠在位于机场边缘的远机位。乘客一般更期待停靠在廊桥,因为这样省去了坐摆渡车前往航站楼的周折。然而,因为廊桥的数量有限,所以这样的愿望不总是能实现。
机场分为国内区和国际区,国内航班飞机只能停靠在国内区,国际航班飞机只能停靠在国际区。一部分廊桥属于国内区,其余的廊桥属于国际区。
L 市新建了一座机场,一共有 个廊桥。该机场决定,廊桥的使用遵循“先到先得”的原则,即每架飞机抵达后,如果相应的区(国内/国际)还有空闲的廊桥,就停靠在廊桥,否则停靠在远机位(假设远机位的数量充足)。该机场只有一条跑道,因此不存在两架飞机同时抵达的情况。
现给定未来一段时间飞机的抵达、离开时刻,请你负责将 个廊桥分配给国内区和国际区,使停靠廊桥的飞机数量最多。
输入格式
输入的第一行,包含三个正整数 ,分别表示廊桥的个数、国内航班飞机的数量、国际航班飞机的数量。
接下来 行,是国内航班的信息,第 行包含两个正整数 ,分别表示一架国内航班飞机的抵达、离开时刻。
接下来 行,是国际航班的信息,第 行包含两个正整数 ,分别表示一架国际航班飞机的抵达、离开时刻。
每行的多个整数由空格分隔。
输出格式
输出一个正整数,表示能够停靠廊桥的飞机数量的最大值。
文件名:airport.cpp
3 5 4
1 5
3 8
6 10
9 14
13 18
2 11
4 15
7 17
12 16
7
2 4 6
20 30
40 50
21 22
41 42
1 19
2 18
3 4
5 6
7 8
9 10
4
见附件中的 airport/airport3.in
见附件中的 airport/airport3.ans
提示
【样例解释 #1】
在图中,我们用抵达、离开时刻的数对来代表一架飞机,如 表示时刻 抵达、时刻 离开的飞机;用 表示该飞机停靠在廊桥,用 表示该飞机停靠在远机位。
我们以表格中阴影部分的计算方式为例,说明该表的含义。在这一部分中,国际区有 个廊桥, 架国际航班飞机依如下次序抵达:
- 首先 在时刻 抵达,停靠在廊桥。
- 然后 在时刻 抵达,停靠在另一个廊桥。
- 接着 在时刻 抵达,这时前 架飞机都还没离开、都还占用着廊桥,而国际区只有 个廊桥,所以只能停靠远机位。
- 最后 在时刻 抵达,这时 这架飞机已经离开,所以有 个空闲的廊桥,该飞机可以停靠在廊桥。
根据表格中的计算结果,当国内区分配 个廊桥、国际区分配 个廊桥时,停靠廊桥的飞机数量最多,一共 架。
【样例解释 #2】
当国内区分配 个廊桥、国际区分配 个廊桥时,停靠廊桥的飞机数量最多,一共 架,即所有的国内航班飞机都能停靠在廊桥。
需要注意的是,本题中廊桥的使用遵循“先到先得”的原则,如果国际区只有 个廊桥,那么将被飞机 占用,而不会被 、、、 这 架飞机先后使用。
【数据范围】
对于 的数据,,。 对于 的数据,,。 对于 的数据,,,,所有 为数值不超过 的互不相同的正整数,且保证对于每个 ,都有 ,以及对于每个 ,都有 。
题解:
#include<bits/stdc++.h>
using namespace std;
struct node {
int x,y,id;
bool operator<( const node& q) const {
return y > q.y;
}
};
bool cmp(node p,node q){
return p.x < q.x;
}
node a[100005],b[100005];
int cnta[100005],cntb[100005];
int main() {
freopen("airport.in","r",stdin);
freopen("airport.out","w",stdout);
int n,m1,m2;
cin >> n >> m1 >> m2;
for(int i=1; i<=m1; i++) {
cin >> a[i].x >> a[i].y;
}
for(int i=1; i<=m2; i++) {
cin >> b[i].x >> b[i].y;
}
sort(a+1,a+m1+1,cmp);
sort(b+1,b+m2+1,cmp);
priority_queue<int> ld;
for(int i=1;i<=n;i++){
ld.push(-i);
}
priority_queue<node> air;
for(int i=1; i<=m1; i++) {
//a[i].x
while(air.size()>0 && air.top().y <= a[i].x ) {
ld.push(-air.top().id);
air.pop();
}
if(ld.size()>0){
a[i].id = -ld.top();
ld.pop();
air.push(a[i]);
cnta[ a[i].id ]++;
}
}
while(air.size()>0)air.pop();
while(ld.size()>0)ld.pop();
for(int i=1;i<=n;i++){
ld.push(-i);
}
for(int i=1; i<=m2; i++) {
//b[i].x
while(air.size()>0 && air.top().y <= b[i].x ) {
ld.push(-air.top().id);
air.pop();
}
if(ld.size()>0){
b[i].id = -ld.top();
ld.pop();
air.push(b[i]);
cntb[ b[i].id ]++;
}
}
// for(int i=1;i<=n;i++){
// cout << cnta[i] << " ";
// }cout << endl;
// for(int i=1;i<=n;i++){
// cout << cntb[i] << " ";
// }cout << endl;
for(int i=1;i<=n;i++){
cnta[i] = cnta[i]+cnta[i-1];
cntb[i] = cntb[i]+cntb[i-1];
}
int ans = 0;
for(int i=0;i<=n;i++){
ans = max(ans,cnta[i] + cntb[n-i]);
}
cout << ans;
return 0;
}