欢迎访问https://blog.csdn.net/lxt_Lucia~~
宇宙第一小仙女\(^o^)/~萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗~
--------------------------------我只是一条可爱哒分界线-------------------------------
今天忽然发现,之前貌似没更过会场安排的博QwQ,今天补上。
(本篇不再举具体题面~ 但给出样例方便测试~ 换汤不换药啦~
无非就两种:
1)多个活动,求活动按时进行所需最少会场数 —— 按起始时间排序。
2)一个会场,多个活动,求可安排最多活动数 —— 按结束时间排序。
(一) 最少会场数 (按起始时间排序)
一、样例
Sample Input
5
1 23
12 28
25 35
27 80
36 50
Sample Output
3
二、思路:
不需要用结构体,将起止时间分别存 a、b 数组里,并分别单独排序。
遍历起始时间,每次都和第 k 个结束时间比较,
若起始时间 小于 该结束时间,则说明冲突,需要再多一个会场,会场数量 ans++;
若起始时间 大于或等于 该结束时间,则说明不冲突,可以使用同一个会场,结束时间下标 k++;
不用担心排序之后的 a[ i ] 、b[ i ] 不对应, 咱们拿样例举个例子:a、b 数组排序之后是
a[ i ] : 1 12 25 27 36
b[ i ] :23 28 35 50 80
(1) 1 < 23,因此它需要一个会场,会场数ans++;
(2) 12 < 23,说明12开始的时候23还没结束,因此它也额外需要一个会场,会场数ans++;
(3) 25 > 23,25开始是时候,23已经结束,说明25开始的活动不会与23结束的活动冲突,因此可以使用同一个会场,结束时间下标 k 也对应向后移一个,k++,对应着28结束;
(4) 27 < 28,说明冲突,会场数ans++;
(5) 36 > 28,说明不冲突,可以使用同一个会场,结束时间下标k++;
我们会发现,其实过程中的 a[ i ] 和 b [ i ] 根本不需要对应同一个活动起止,我们还是会拿 它的起始时间 和 在它之前占用会场的活动的结束时间 进行比较。
总而言之,就是站在会场的角度按起始时间先后逐个进行活动,如果下一个活动进行时前一个还没结束,则需多一个会场,否则即可共用同一个。
三、代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, k = 0, ans = 0;
scanf("%d", &n);
int a[n], b[n];
for(int i=0; i<n; i++)
scanf("%d %d", &a[i], &b[i]);
sort(a, a+n), sort(b, b+n);
for(int i=0; i<n; i++)
a[i] < b[k] ? ans++ : k++;
printf("%d\n", ans);
return 0;
}
(二) 最多活动数 (按结束时间排序)
一、样例
(起止时间可以相等样例)
Sample Input
2
1 10
10 11
3
1 10
10 11
11 20
Sample Output
2
3
(起止时间不能相等样例)
Sample Input
2
1 10
10 11
3
1 10
10 11
11 20
Sample Output
1
2
二、思路:
定义结构体Time 存每个活动起止时间,按照活动结束时间排序,limit 代表上一个活动的结束时间。
若上一个活动的结束时间 >= 下一个活动起始时间,则说明上一个活动已结束,可进行下一个,因此活动数ans++,limit 更新为下一个活动的结束时间。否则该活动无法进行。
这里需要注意:有的题目规定 上一个活动的结束时间 和 下一个活动起始时间 不能相等,只需将判断条件改为 > 即可。
三、代码:
#include <bits/stdc++.h>
using namespace std;
struct Time
{
int left;
int right;
};
bool cmp(Time x, Time y)
{
if(x.right != y.right)
return x.right < y.right;
else
return x.left < y.left;
}
int main()
{
int n, ans = 1;
scanf("%d", &n);
struct Time a[n];
for(int i=0; i<n; i++)
scanf("%d %d", &a[i].left, &a[i].right);
sort(a, a+n, cmp);
int limit = a[0].right; //上一个活动的结束时间,初始化为第一个活动结束时间
for(int i=1; i<n; i++)
{
if(a[i].left >= limit) //若上一个活动结束时间不能等于下一个活动起始时间,则改为 >
{
ans++;
limit = a[i].right;
}
}
printf("%d\n", ans);
return 0;
}