一年一度的快手运动会又要开始了,同学们终于有一天可以离开鼠标键盘显示器,全身心的投入到各种体育项目中。UED设计师小红虽然没有参加体育项目,但她的责任重大,因为她是拉拉队的队长,她需要在每个项目中为参赛的同学们加油助威。
因为运动会的项目众多,很多项目在同一时间会同时进行着。作为拉拉队长,小红需要遵守以下规则:
不能同时给多个体育项目加油助威
给每个体育项目加油的时长必须超过项目时长的一半,每个体育项目只能加油一次
体育项目的开始和结束时间都是整点,如果项目进行到一半想要离开,也只能选择整点离开
不考虑往返于各个体育项目比赛场地中花费的时间
请帮小红设计一个算法,在已知所有体育项目日程的前提下,计算是否能在每个体育项目中为参赛的同学们加油。
说明:
如果体育项目时长为2,超过时长的一半为2;
如果体育项目时长为3,超过时长的一半为2;
如果体育项目时长为4,超过时长的一半为3;
输入描述:
输入包括1+N行 第一行输入一个整数N, 1 <= N <= 10,表示今天要参加多少个讨论会 后续N行,每行输入开始和结束时间,均为整数,用空格分隔,0 <= startTime < endTime <= 24
输出描述:
输出包括一行 如果小红能够参加全部讨论会,返回1 如果小红不能够参加全部讨论会,返回-1
输入例子1:
3 3 10 1 5 4 6
输出例子1:
1
这道题关键有点像关键路径,要记录最早开始时间和最晚开始时间,按照最晚开始时间排序,越前的越着急,但是不要拖拉,能提前开始就尽量提前开始,给后面留出时间,遍历每一个,要考虑现在是否位于项目的最早开始时间及之后,然后判断是否早于最晚开始时间。
#include<stdio.h>
#include<algorithm>
using namespace std;
struct Node{
int start_time;
int last_start_time;
int halftime;
};
Node nodes[15];
bool cmp(const Node &a,const Node &b){
if(a.last_start_time!=b.last_start_time)
return a.last_start_time<b.last_start_time;
return a.start_time<b.start_time;
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
int start_time,end_time;
scanf("%d%d",&start_time,&end_time);
int halftime=end_time-start_time;
if(halftime==2){
halftime=2;
}
else if(halftime==3){
halftime=2;
}
else if(halftime==4){
halftime=3;
}
else{
if(halftime%2==0)
halftime=halftime/2;
else
halftime=(halftime+1)/2;
}
nodes[i].start_time=start_time;
nodes[i].last_start_time=end_time-halftime;
nodes[i].halftime=halftime;
}
sort(nodes,nodes+n,cmp);
int ok_time=nodes[0].start_time;
int tag=1;
for(int i=0;i<n;i++){
ok_time=max(ok_time,nodes[i].start_time);
if(ok_time<=nodes[i].last_start_time){
ok_time=ok_time+nodes[i].halftime;
}
else{
tag=0;
break;
}
}
if(tag==1)
printf("1\n");
else{
printf("-1\n");
}
}