P7913 [CSP-S 2021] 廊桥分配(暂未AC)

廊桥分配

题目描述

当一架飞机抵达机场时,可以停靠在航站楼旁的廊桥,也可以停靠在位于机场边缘的远机位。乘客一般更期待停靠在廊桥,因为这样省去了坐摆渡车前往航站楼的周折。然而,因为廊桥的数量有限,所以这样的愿望不总是能实现。

机场分为国内区和国际区,国内航班飞机只能停靠在国内区,国际航班飞机只能停靠在国际区。一部分廊桥属于国内区,其余的廊桥属于国际区。

L 市新建了一座机场,一共有 n 个廊桥。该机场决定,廊桥的使用遵循“先到先得”的原则,即每架飞机抵达后,如果相应的区(国内/国际)还有空闲的廊桥,就停靠在廊桥,否则停靠在远机位(假设远机位的数量充足)。该机场只有一条跑道,因此不存在两架飞机同时抵达的情况。

现给定未来一段时间飞机的抵达、离开时刻,请你负责将 n 个廊桥分配给国内区和国际区,使停靠廊桥的飞机数量最多。

输入格式

输入的第一行,包含三个正整数 n,m1​,m2​,分别表示廊桥的个数、国内航班飞机的数量、国际航班飞机的数量。

接下来 m1​ 行,是国内航班的信息,第 i 行包含两个正整数a1,i​,b1,i​,分别表示一架国内航班飞机的抵达、离开时刻。

接下来 m2​ 行,是国际航班的信息,第 i 行包含两个正整数a2,i​,b2,i​,分别表示一架国际航班飞机的抵达、离开时刻。

每行的多个整数由空格分隔。

输出格式

输出一个正整数,表示能够停靠廊桥的飞机数量的最大值。

输入输出样例

输入 #1复制

3 5 4
1 5
3 8
6 10
9 14
13 18
2 11
4 15
7 17
12 16

输出 #1复制

7

输入 #2复制

2 4 6
20 30
40 50
21 22
41 42
1 19
2 18
3 4
5 6
7 8
9 10

输出 #2复制

4

输入 #3复制

见附件中的 airport/airport3.in

输出 #3复制

见附件中的 airport/airport3.ans

说明/提示

【样例解释 #1】

在图中,我们用抵达、离开时刻的数对来代表一架飞机,如 (1,5) 表示时刻 1 抵达、时刻 5 离开的飞机;用 √ 表示该飞机停靠在廊桥,用 × 表示该飞机停靠在远机位。

我们以表格中阴影部分的计算方式为例,说明该表的含义。在这一部分中,国际区有 2 个廊桥,4 架国际航班飞机依如下次序抵达:

  1. 首先 (2,11) 在时刻 22 抵达,停靠在廊桥。
  2. 然后 (4,15) 在时刻 44 抵达,停靠在另一个廊桥。
  3. 接着 (7,17) 在时刻 7 抵达,这时前 2 架飞机都还没离开、都还占用着廊桥,而国际区只有 2 个廊桥,所以只能停靠远机位。
  4. 最后 (12,16) 在时刻 12 抵达,这时(2,11) 这架飞机已经离开,所以有 1 个空闲的廊桥,该飞机可以停靠在廊桥。

根据表格中的计算结果,当国内区分配 2 个廊桥、国际区分配 1 个廊桥时,停靠廊桥的飞机数量最多,一共 7 架。

【样例解释 #2】

当国内区分配 22 个廊桥、国际区分配 00 个廊桥时,停靠廊桥的飞机数量最多,一共 44 架,即所有的国内航班飞机都能停靠在廊桥。

需要注意的是,本题中廊桥的使用遵循“先到先得”的原则,如果国际区只有 1 个廊桥,那么将被飞机 (1,19) 占用,而不会被 (3,4)、(5,6)、(7,8)、(9,10) 这 4 架飞机先后使用。

【数据范围】

对于 20% 的数据,n≤100,m1​+m2​≤100。
对于 40% 的数据,n≤5000,m1​+m2​≤5000。
对于 100% 的数据,1≤n≤10^5,m1​,m2​≥1,m1​+m2​≤10^5,所有a1,i​,b1,i​,a2,i​,b2,i​ 为数值不超过 10^8 的互不相同的正整数,且保证对于每个i∈[1,m1​],都有 a1,i​<b1,i​,以及对于每个 i∈[1,m2​],都有a2,i​<b2,i​。

【感谢 hack 数据提供】

附件下载

airport.zip1.89KB

代码 :

1.45

#include <bits/stdc++.h>
using namespace std;
int n,m1,m2;
struct dz{
	int da,zo;
}a[1000010],b[1000010];
priority_queue<int,vector<int>,greater<int> > q1;
priority_queue<int,vector<int>,greater<int> > q2;
int sum;
int maxn=0;
bool cmp(dz x,dz y){
	return x.da<y.da;
}
int main(){
	cin >> n >> m1 >> m2;
	for(int i = 1;i<=m1;i++) cin >> a[i].da>>a[i].zo;
	for(int i = 1;i<=m2;i++) cin >> b[i].da>>b[i].zo;
	sort(a+1,a+m1+1,cmp);
	sort(b+1,b+m2+1,cmp);//先到先得 
	for(int i = 0;i<=n;i++){
		if(i*(m1+m2)>5e7) break;//因为总会超时,赌一把算前面的能不能算到结果 
		sum=0;//sum初始化为0 
		while(q1.size()) q1.pop();
		while(q2.size()) q2.pop();
		//两个队列初始化为0 其实也可以直接在这个循环里定义,就不需要清空
		//即把7,8两行换到23,24上 
		for(int j = 1;j<=m1;j++){
			if(q1.size()&&(q1.top()<a[j].da)) q1.pop();
			//如果廊桥里还有飞机并且队头的离开时间小于第j架的到达时间 
			if(q1.size()<i){//如果廊桥有空的 
				q1.push(a[j].zo);//把飞机的离开时间放里面 
				sum++;
			}
		}
		for(int j = 1;j<=m2;j++){
			if(q2.size()&&(q2.top()<b[j].da)) q2.pop();
			if(q2.size()<n-i){
				q2.push(b[j].zo);
				sum++;
			}
		}
		maxn=max(maxn,sum);//取出最大值 
	}
	cout << maxn;
	return 0;
}

2.AC没写and不会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值