礼堂
学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动。现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。
输入:第一行是一个整型数m(m<100)表示共有m组测试数据。
每组测试数据的第一行是一个整数n(1<n<10000)表示该测试数据共有n个活动。随后的n行,每行有两个正整数Bi,Ei(0<=Bi,Ei<10000),分别表示第i个活动的起始与结束时间(Bi<=Ei)
输出:对于每一组输入,输出最多能够安排的活动数量。每组的输出占一行。
样例输入:
2
2
1 10
10 11
3
1 10
10 11
11 20
样例输出:
1
2
提示:如果上一个活动在t时间结束,下一个活动最早应该在t+1时间开始
//此题采用贪心法解决,贪心法总是选取当前最优解,在此题中,先按照结束时间进行活动排序,然后开始依次寻找相容性最大的活动集合(直至无法找到下一个可以进行的活动,结束寻找)
//需要特别注意的是,如果选用效率较低的排序方法,如冒泡排序或者选择排序,时间复杂度为O(n*n),就会发生超时,所以采用快排
代码如下,欢迎指正:
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10000+5;
typedef struct{int s,e;}Data;
Data time[maxn];
void quick_sort(int left,int right)
{
if(left>right) return;
int i,j,temp;
Data temptime;
temp=time[left].e;
temptime=time[left];
i=left;
j=right;
while(i!=j)
{
while(time[j].e>=temp&&i<j)
j--;
while(time[i].e<=temp&&i<j)
i++;
swap(time[i],time[j]);
}
time[left]=time[i];
time[i]=temptime;
quick_sort(left,i-1);
quick_sort(i+1,right);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int m;
scanf("%d",&m);
for(int i=0;i<m;i++)
scanf("%d%d",&time[i].s,&time[i].e);
quick_sort(0,m-1);
int t=1;
for(int i=0;i<m-1;)
{
int n=0;
for(int j=i+1;j<m;j++)
if(time[i].e<time[j].s)
{
i=j;
t++;
n++;
break;
}
if(!n) break;
}
cout<<t<<endl;
}
return 0;
}
然而,当接触到pair时,代码就会变得更为简洁,pair和sort联合起来使用,代码大大简化
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10000+5;
typedef pair<int,int>PII;
PII p[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int m;
scanf("%d",&m);
for(int i=0;i<m;i++)
scanf("%d%d",&p[i].second,&p[i].first);//按照结束时间进行活动排序
sort(p,p+m);
//t为最后所选活动的结束时间,下面的方法不是通用方法,当开始时间可以为0时,下面的寻找方法是错误的,开始时间为0时,它无法完成t的初始赋值
/* int t=0,ans=0;
for(int i=0;i<m;i++)
if(t<p[i].second) {
ans++;
t=p[i].first;
}
cout<<ans<<endl; */
//通用方法如下
int ans=1,t=p[0].first;
for(int i=1;i<m;i++)
if(t<p[i].second) {
ans++;
t=p[i].first;
}
cout<<ans<<endl;
}
return 0;
}