题目描述
假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个算法进行安排。
输入
第一行一个n(n<=10000)代表任务总数
第二行到第(n + 1)行包含n个开始时间和结束时间。
开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000
输出
输出最小需要多少会场数
样例输入 5 1 23 12 28 25 35 27 80 36 50 样例输出 3
分析
一个活动的安排,取决于该活动的开始时间和上一个活动的结束时间是否冲突。
所以先将所有活动按开始时间升序进行排序。
然后循环安排活动,遍历每一个活动,
如果这个活动的开始时间大于上一个活动的结束时间且该活动还未被安排,
则可以和上一个活动安排到同一个会场
尽可能安排最多活动,只要时间不冲突,就在同一个会场,接下来再循环一遍,安排剩下的活动,又是一个会场,直到所有活动都被安排完。
例如:
1 23
12 28
25 35
27 80
36 50
第一轮:
1 23
25 35
36 50
第二轮:
12 38
第三轮
27 80
所以经过三轮可以将所有活动安排完,也就是说需要至少三个会场
代码
#include<stdio.h>
typedef struct{
int start;//开始时间
int end;//结束时间
int flag;//是否被安排
}Activity;
int Pation(Activity A[],int low,int high){
int p = A[low].start;
Activity pA = A[low];
while(low < high){
while(low < high && p <= A[high].start) --high;
A[low] = A[high];
while(low < high && p >= A[low].start) ++low;
A[high] = A[low];
}
A[low] = pA;
return low;
}
void QuickSort(Activity A[],int low,int high){
if(low < high){
int p = Pation(A,low,high);
QuickSort(A,low,p-1);
QuickSort(A,p+1,high);
}
}
void solve(Activity A[],int n){
QuickSort(A,1,n);//按开始时间升序排序
int count = 0;//已经被安排的活动数
int sum = 0;//会场数
int last = 0;//上一个活动的结束时间
while(n-count > 0) {
for(int i = 1; i <= n; i++){
/*如果这个活动的开始时间大
于上一个活动的结束时间且该活动还未被安排,
则可以和上一个活动安排到同一个会场 */
if(A[i].flag == 0 && A[i].start >= last){
A[i].flag = 1;//安排该活动
last = A[i].end;
count++;
}
}
sum++;//开启新的会场
last = 0;
}
printf("%d",sum);
}
int main(){
int n;
scanf("%d",&n);
Activity A[n+1];
for(int i = 1; i <= n; i++){
scanf("%d %d",&A[i].start,&A[i].end);
A[i].flag = 0;
}
solve(A,n);
return 0;
}