运动会

一年一度的快手运动会又要开始了,同学们终于有一天可以离开鼠标键盘显示器,全身心的投入到各种体育项目中。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");
    }
    
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值