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