猫睡觉问题
题意
众所周知,TT家里有一只魔法喵。这只喵十分嗜睡。一睡就没有白天黑夜。喵喵一天可以睡多次!!每次想睡多久就睡多久╭(╯^╰)╮
喵睡觉的时段是连续的,即一旦喵喵开始睡觉了,就不能被打扰,不然喵会咬人哒[○・`Д´・ ○]
可以假设喵喵必须要睡眠连续不少于 A 个小时,即一旦喵喵开始睡觉了,至少连续 A 个小时内(即A*60分钟内)不能被打扰!
现在你知道喵喵很嗜睡了,它一天的时长都在吃、喝、拉、撒、睡,换句话说要么睡要么醒着滴!
众所周知,这只魔法喵很懒,和TT一样懒,它不能连续活动超过 B 个小时。
猫主子是不用工作不用写代码滴,十分舒适,所以,它是想睡就睡滴。
但是,现在猫主子有一件感兴趣的事,就是上BiliBili网站看的新番。
新番的播放时间它已经贴在床头啦(每天都用同一张时间表哦),这段时间它必须醒着!!
作为一只喵喵,它认为安排时间是很麻烦的事情,现在请你帮它安排睡觉的时间段。
思路
本题初看相比上次的会议安排简单。困难点主要有三:格式读入输出、时间闭区间、循环安排。
读入采用的方法是读取一行字符串,并根据格式取相应索引解析出起止时间信息,存入TIME
结构体数组play
。显示答案时格式输出时间信息即可。
时间闭区间的处理是容易出错的地方,为此在TIME
结构体中重载了特殊的减法,将计算结果与代表A小时和B小时的TIME
结构体比较,还提供了p1m()和m1m()两个方法,方便放送时间和睡觉时间互相转换。
时间循环的处理方式如下:首先检查所有放送时间的间隔,如果间隔超过A即可睡觉,将该段时间的最大长度(即前一次放送结束1min到后一次放送开始前1min)加入TIME
结构体数组sleep
,否则跳过,这就是“最有可能满足要求”的安排。接着检查这一睡觉安排是否可行:检查每两个睡时间隔是否超过最大醒时,若全部未超过则该安排可行。这样的处理方式下,只需要在扫描过程中判断一次数组首尾元素关系即可环形判断。
Debug
本题第一个费时的调试点在闭区间的时间段处理上。因为将小时和分钟分开记录,进位和取模的细节较为繁琐,还会出现24:00和00:-1之类的显示。
第二个排查出的bug为对安排可行的判断。有一种情况是第一次处理完后,没有可睡觉的时间段,这时在接下来的处理中是排查不出安排不可行的。添加了对这种情况的判断。
但就是这种情况的一个小细节导致了大量浪费时间的查错:此处的输出没有和一开始一样注意到文本的大小写。
代码
#include<iostream>
#include<string>
#include<algorithm>
#include<iomanip>
using namespace std;
struct TIME{
int hh;
int mm;
int type;//0��ʼ��1����
void p1m(){
mm++;
if(mm>=60){
mm-=60;
hh++;
}
if(hh>=24){
hh-=24;
}
}
void m1m(){
mm--;
if(mm<=-1){
mm+=60;
hh--;
}
if(hh<=-1){
hh+=24;
}
}
void operator=(TIME& t){
hh=t.hh;
mm=t.mm;
type=t.type;
}
bool operator<(const TIME& t)const{
if(hh!=t.hh)return hh<t.hh;
return mm<t.mm;
}
bool operator>(const TIME& t)const{return t<*this;}
bool operator>=(const TIME& t)const{return !(*this<t);}
bool operator<=(const TIME& t)const{return !(t<*this);}
bool operator==(const TIME& t)const{return !(*this<t)&&!(t<*this);}
bool operator!=(const TIME& t)const{return (*this<t)||(t<*this);}
TIME operator-(TIME& t){
TIME temp;
temp=*this;
if(temp.mm<t.mm){
temp.mm+=60;
temp.hh--;
}
temp.mm-=t.mm;
if(temp.hh<t.hh)temp.hh+=24;
temp.hh-=t.hh;
if(temp.hh==0&&temp.mm==0){
temp.mm=-2;
return temp;
}
if(temp.hh==0&&temp.mm==1){
temp.mm=-1;
return temp;
}
if(temp.mm<2){
temp.mm+=60;
temp.hh--;
}
temp.mm-=2;
return temp;
}
void setHour(int x){
mm=59;
hh=x-1;
}
};
void deal(string str,TIME& a,TIME& b){
int h,m;
h=str[0]-'0';
h*=10;
h+=(str[1]-'0');
a.hh=h;
m=str[3]-'0';
m*=10;
m+=(str[4]-'0');
a.mm=m;
a.type=0;
h=str[6]-'0';
h*=10;
h+=(str[7]-'0');
b.hh=h;
m=str[9]-'0';
m*=10;
m+=(str[10]-'0');
b.mm=m;
b.type=1;
}
void output(TIME A,TIME B){
cout<<setw(2)<<setfill('0')<<A.hh<<":";
cout<<setw(2)<<setfill('0')<<A.mm<<"-";
cout<<setw(2)<<setfill('0')<<B.hh<<":";
cout<<setw(2)<<setfill('0')<<B.mm<<endl;
}
int A,B,N;
int pSZ,sSZ;
TIME play[50];
TIME sleep[50];
string playTIME;
TIME tempA,tempB;
TIME Ahour,Bhour;
int main(){
while(cin>>A>>B>>N){
pSZ=sSZ=0;
Ahour.setHour(A);
Bhour.setHour(B);
for(int i=1;i<=N;i++){
cin>>playTIME;
deal(playTIME,tempA,tempB);
play[++pSZ]=tempA;
play[++pSZ]=tempB;
}
sort(play+1,play+pSZ+1);
if(play[1].type==1){
for(int i=1;i<pSZ;i+=2){
if(play[i+1]-play[i]>=Ahour){
play[i].p1m();
sleep[++sSZ]=play[i];
sleep[sSZ].type=0;
play[i+1].m1m();
sleep[++sSZ]=play[i+1];
sleep[sSZ].type=1;
}
}
}else{
for(int i=2;i<pSZ-1;i+=2){
if(play[i+1]-play[i]>=Ahour){
play[i].p1m();
sleep[++sSZ]=play[i];
sleep[sSZ].type=0;
play[i+1].m1m();
sleep[++sSZ]=play[i+1];
sleep[sSZ].type=1;
}
}
if(play[1]-play[pSZ]>=Ahour){
play[pSZ].p1m();
sleep[++sSZ]=play[pSZ];
sleep[sSZ].type=0;
play[1].m1m();
sleep[++sSZ]=play[1];
sleep[sSZ].type=1;
}
}
if(sSZ==0){
cout<<"No"<<endl;//��Сд��mmml��
continue;
}
int jdg=0;
for(int i=2;i<sSZ;i+=2){
if(sleep[i+1]-sleep[i]>Bhour){
jdg=1;
break;
}
}
if(sleep[1]-sleep[sSZ]>Bhour)jdg=1;
if(jdg)cout<<"No"<<endl;
else{
cout<<"Yes"<<endl<<sSZ/2<<endl;
for(int i=1;i<sSZ;i+=2){
output(sleep[i],sleep[i+1]);
}
}
}
}