Week14 猫睡觉问题

题意:
众所周知,TT家里有一只魔法喵。这只喵十分嗜睡。一睡就没有白天黑夜。喵喵一天可以睡多次!!每次想睡多久就睡多久╭(╯^╰)╮
喵睡觉的时段是连续的,即一旦喵喵开始睡觉了,就不能被打扰,不然喵会咬人哒[○・`Д´・ ○]
可以假设喵喵必须要睡眠连续不少于 A 个小时,即一旦喵喵开始睡觉了,至少连续 A 个小时内(即A*60分钟内)不能被打扰!
现在你知道喵喵很嗜睡了,它一天的时长都在吃、喝、拉、撒、睡,换句话说要么睡要么醒着滴!
众所周知,这只魔法喵很懒,和TT一样懒,它白天不能连续活动超过 B 个小时。
猫主子是不用工作不用写代码滴,十分舒适,所以,它是想睡就睡滴。
但是,现在猫主子有一件感兴趣的事,就是上BiliBili网站看的新番。
新番的播放时间它已经贴在床头啦(每天都用同一张时间表哦),这段时间它必须醒着!!
作为一只喵喵,它认为安排时间是很麻烦的事情,现在请你帮它安排睡觉的时间段。
思路:
这题是模拟题,但是处理起来很复杂,又有不少坑。在咨询了同学之后,终于明白该怎么做。

  1. 两个区间中间相隔的时间小于A的区间合并,这样剩下的睡觉时间都可以睡A小时(只剩一个区间需要特判一下)。
  2. 判断合并完毕的区间持续时间是否超过了B小时,如果超过,那就输出"No",否则,输出剩下能睡觉的时间即可。
  3. 注意闭区间和新的一天。
    代码:
#include <iostream>
#include <algorithm>
using namespace std;

struct timeNode
{
    timeNode(int _h = 0, int _min = 0) : h(_h), minute(_min) {}
    timeNode operator-(const timeNode &t)
    {
        timeNode tempt(h, minute);
        if (tempt < t)
        {
            tempt.h += 24;
        }
        if (tempt.minute < t.minute)
        {
            tempt.h -= 1;
            tempt.minute += 60;
        }
        tempt.minute -= t.minute;
        tempt.h -= t.h;
        return tempt;
    }
    bool operator<(const timeNode &t)
    {
        if (h < t.h)
            return true;
        else if (h > t.h)
            return false;
        else
            return minute < t.minute;
    }
    bool operator>(const timeNode &t)
    {
        if (h > t.h)
            return true;
        else if (h < t.h)
            return false;
        else
            return minute > t.minute;
    }
    timeNode &operator=(const timeNode &t)
    {
        h = t.h;
        minute = t.minute;
        return *this;
    }
    int h, minute;
};
timeNode &minus1min(timeNode &t)
{ 
    timeNode tempt = t;
    if (tempt.minute == 0)
    {
        if (tempt.h == 0)
            tempt.h += 24;
        tempt.h--;
        tempt.minute += 60;
    }
    tempt.minute--;
    return tempt;
}
timeNode &plus1min(timeNode &t)
{ 
    timeNode tempt = t;
    tempt.minute += 1;
    if (tempt.minute == 60)
    {
        tempt.minute = 0;
        tempt.h++;
    }
    if (tempt.h == 24)
        tempt.h = 0;
    return tempt;
}
struct timeInterval
{ 
    timeInterval() {}
    timeInterval(struct timeNode _st, struct timeNode _et)
    {
        startTime = _st;
        endTime = _et;
    };
    bool operator<(const timeInterval &t) { return startTime < t.startTime; }
    timeInterval &operator=(const timeInterval &t)
    {
        startTime = t.startTime;
        endTime = t.endTime;
        return *this;
    }
    timeNode startTime, endTime;
};
timeInterval tiInt[24];
int a, b, n, cnt;
bool comp(timeInterval &_a, timeInterval &_b)
{
    return _a < _b;
}
int main()
{
    while (scanf("%d %d %d", &a, &b, &n) != EOF)
    {
        timeNode A(a, 1), B(b - 1, 59); 
        bool flag = true;
        cnt = 0;
        for (int i = 1; i <= n; i++)
        {
            int a1, a2, a3, a4;
            scanf("%d:%d-%d:%d", &a1, &a2, &a3, &a4);
            timeNode t1(a1, a2), t2(a3, a4);
            tiInt[++cnt].startTime = t1;
            tiInt[cnt].endTime = t2;
        }
        sort(tiInt + 1, tiInt + 1 + cnt, comp);
        for (int i = 1; i < cnt; i++)
        { 
            if (tiInt[i + 1].startTime - tiInt[i].endTime < A)
            { 
                tiInt[i].endTime = tiInt[i + 1].endTime;
                for (int j = i + 1; j < cnt; j++) //向前挪
                    tiInt[j] = tiInt[j + 1];
                cnt--;
                i--;
            }
        }
        if (cnt != 1 && tiInt[1].startTime - tiInt[cnt].endTime < A)
        {
            tiInt[cnt].endTime = tiInt[1].endTime;
            for (int i = 1; i < cnt; i++)
                tiInt[i] = tiInt[i + 1];
            cnt--;
        }
        for (int i = 1; i <= cnt; i++)
        { 
            if (tiInt[i].endTime - tiInt[i].startTime > B)
            {
                flag = false;
                break;
            }
        }
        if (!flag)
        {
            printf("No\n");
            continue;
        }
        if (cnt == 1 && tiInt[1].startTime - tiInt[1].endTime < A)
        {
            printf("No\n");
            continue;
        }
        printf("Yes\n%d\n", cnt);
        for (int i = 1; i <= cnt; i++)
        {
            timeNode t1 = plus1min(tiInt[i % cnt == 0 ? cnt : i % cnt].endTime);
            timeNode t2 = minus1min(tiInt[(i + 1) % cnt == 0 ? cnt : (i + 1) % cnt].startTime);
            printf("%02d:%02d-%02d:%02d\n", t1.h, t1.minute, t2.h, t2.minute);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值