活动调度
一.题目要求:输入要求:
第一行为活动的个数 N(1<=N<=1 000 000) 。
接下来 N 行为 Si 和 Fi(0<=Si<Fi<=2 000 000 000) ,分别代表第 i 个活动的开始时间和结束时间。活动 i 的区间段为 [Si,Fi)
输出要求:
输出有一行 M ,为所需教室的最小数量。
二.题目分析
本人看了几篇借题报告总结了一下比较好的思想。我们可以想象每个活动是时间轴一条线段,开始时间为线段
起点,结束时间为线段终点,时间轴上任意一点,比如 t 点,这一点被 n 条线段覆盖,则在这一时间
点上至少需要n间教室,则整个时间轴上所有点的n的最大值即为答案。
三.实现方法
想象从时间轴0处向无穷处出发,遇到一个线段的起点,则占用教室+1,遇到一个终点,则-1,遍历过程中更
新这个占用的最大值。我的代码把起点和终点放在一起排列,用flag标记起点还是终点,这里要特别注意的
是,当起点时间和终点的时间一样时,要把终点排在前面,原因就请你来思考一下了。哈哈?
下面是AC代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node//用来存每一个时间节点
{
long long time;
int flag;//-1表示此点为起点,+1表示为终点
}T[2000006];
bool cmp(struct node x, struct node y)
{
if (x.time != y.time)
return x.time < y.time;
else//特别注意此处
return x.flag > y.flag;
}
int main()
{
int n;
int sum = 0,ans=0;//sum用来记录时间节点数,ans为最终的答案
long long start, end;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%lld %lld", &start, &end);
T[sum].time = start; T[sum++].flag = -1;
T[sum].time = end; T[sum++].flag = 1;
}
sort(T, T + sum, cmp);
int temp = 0;
for (int i = 0; i < sum; i++)
{
if (T[i].flag == -1)
temp++;
else if (T[i].flag == 1)
temp--;
if (temp > ans)//更新最大值
ans=temp;
}
printf("%d\n", ans);
return 0;
}