列表

详情


NC229942. [CSP2021]廊桥分配(airport)

描述

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

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

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

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

输入描述

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

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

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

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

输出描述

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

示例1

输入:

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

输出:

7

说明:

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

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

1.首先 (2, 11) 在时刻2抵达,停靠在廊桥

2.然后 (4, 15) 在时刻4抵达,停靠在另一个廊桥

3.接着 (7, 17) 在时刻7抵达,这时前2架飞机都还没离开、都还占用着廊桥,而国际区只有2个廊桥,所以只能停靠远机位

4.最后 (12, 16) 在时刻12抵达,这时 (2 11) 这架飞机已经离开,所以有1个空闲的廊桥,该飞机可以停廊桥

根据表格中的计算结果,当国内区分配2个廊桥、国际区分配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

输出:

4

说明:

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

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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 130ms, 内存消耗: 5124K, 提交时间: 2023-04-06 13:56:27

#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> PII;
const int N = 100010;

int f[N],g[N];

void check(int m,int f[])
{
	set<PII> b;
	for(int i=1;i<=m;i++)
	{
		int l,r;cin>>l>>r;
		b.insert({l,r});
	}
	for(int i=1;i<=m;i++)
	{
		auto it=b.begin();
		while(it!=b.end())
		{
			f[i]++;
			int r=it->second;
			b.erase(it);
			it=b.upper_bound({r,-1});
		}
	}
}

int main()
{
	int n,m1,m2;cin>>n>>m1>>m2;
	
	check(m1,f);
	check(m2,g);
	
	for(int i=1;i<=n;i++) f[i]+=f[i-1];
	for(int i=1;i<=n;i++) g[i]+=g[i-1];
	
	int ans=0;
	for(int i=0;i<=n;i++)
		ans=max(ans,f[i]+g[n-i]);
	cout<<ans;

	return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 131ms, 内存消耗: 5116K, 提交时间: 2023-04-06 14:26:25

#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> PII;
const int N = 100010;

int f[N],g[N];

void check(int m,int a[])
{
	set<PII> b;
	for(int i=1;i<=m;i++)
	{
		int l,r;cin>>l>>r;
		b.insert({l,r});
	}
	for(int i=1;i<=m;i++)
	{
		auto it=b.begin();
		while(it!=b.end())
		{
			a[i]++;
			int r=it->second;
			b.erase(it);
			it=b.upper_bound({r,-1});
		}
	}
}

int main()
{
	int n,m1,m2;cin>>n>>m1>>m2;
	
	check(m1,f);
	check(m2,g);
	
	for(int i=1;i<=n;i++) f[i]+=f[i-1];
	for(int i=1;i<=n;i++) g[i]+=g[i-1];
	
	int ans=0;
	for(int i=0;i<=n;i++)
		ans=max(ans,f[i]+g[n-i]);
	cout<<ans;

	return 0;
}

上一题