时间模拟:猫猫看番问题

题面:

猫是嗜睡的动物。一睡就没有白天黑夜。喵喵一天可以睡多次!!每次想睡多久就睡多久
喵睡觉的时段是连续的,即一旦喵喵开始睡觉了,就不能被打扰,不然喵会咬人
可以假设喵喵必须要睡眠连续不少于 A 个小时,即一旦喵喵开始睡觉了,至少连续 A 个小时内(即A*60分钟内)不能被打扰!
猫的状态要么睡要么醒着滴!
猫很懒,它不能连续活动超过 B 个小时,猫是想睡就睡的。
现在猫主子有一件感兴趣的事,就是上BiliBili网站看的新番,在新番播放的这段时间它必须醒着!
作为一只喵喵,它认为安排时间是很麻烦的事情,现在请你帮它安排睡觉的时间段

多组数据,多组数据,多组数据哦,每组数据的格式如下:
第1行输入三个整数,A 和 B 和 N (1 <= A <= 24, 1 <= B <= 24, 1 <= n <= 20)
第2到N+1行为每日的新番时间表,每行一个时间段,格式形如 hh:mm-hh:mm (闭区间),这是一种时间格式,hh:mm 的范围为 00:00 到 23:59。注意一下,时间段是保证不重叠的,但是可能出现跨夜的新番,即新番的开始时间点大于结束时间点。

保证每个时间段的开始时间点和结束时间点不一样,即不可能出现类似 08:00-08:00 这种的时间段。时长的计算由于是闭区间所以也是有点坑的,比如 12:00-13:59 的时长就是 120 分钟。

不保证输入的新番时间表有序

我们知道,时间管理是一项很难的活,所以你可能没有办法安排的那么好,使得这个时间段满足喵喵的要求,即每次睡必须时间连续且不少于 A 小时,每次醒必须时间连续且不大于 B 小时,还要能看完所有的番,所以输出的第一行是 Yes 或者 No,代表是否存在满足猫猫要求的时间管理办法。
然后,对于时间管理,你只要告诉喵喵,它什么时候睡觉即可。

即第2行输出一个整数 k,代表当天有多少个时间段要睡觉

接下来 k 行是喵喵的睡觉时间段,每行一个时间段,格式形如 hh:mm-hh:mm (闭区间),这个在前面也有定义。注意一下,如果喵喵的睡眠时段跨越当天到达了明天,比如从23点50分睡到0点40分,那就输出23:50-00:40,如果从今晚23:50睡到明天早上7:30,那就输出23:50-07:30。
输出要排序吗?(输出打乱是能过的,也就是说,题目对输出的那些时间段间的顺序是没有要求的)

本题是 Special Judge

sample input:
12 12 1
23:00-01:00
3 4 3
07:00-08:00
11:00-11:09
19:00-19:59

sample output:
Yes
1
01:07-22:13
No

注意:

本题最麻烦的是最后一个番到第二天第一个番的时间段的处理
注意给定的例子是有顺序的,但是注意题里有说明不保证输入的时间表是有序的,所以在创建结构体的时候要重写比较符,在完成输入后首先对于时间表进行排序

思路:

  • 因为对于睡眠的限制是至少睡A,所以选择睡眠的最大值,即能睡就睡
  • 因为读入的时间有小时有分钟,为了更好的计算,选择都化成分钟进行比较。如果结束的时间比开始的时间小,说明这个番跨了一天,那么结束时间加上一天的分钟数然后再进行计算
  • 如果一个番的时长大于能醒着的最大时间,那么直接可以判定为不可能
  • 将所有番的时间表进行排序后,利用一个结构体来记录喵从什么时候开始是醒着的,来判断是否能继续看番,记录上一个番的结束时间来判断能否睡觉
  • 如果不能睡觉,就要判断上是否可以继续看,是否上一次醒来到这个番结束的时间超过了能醒着的最大时长。注意要对跨天的番进行特殊处理
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
struct tim
{
 int start;  //开始时间, 
 int end;   //结束时间 
 bool operator <(const tim &t)const
 {
  if(start!=t.start) return start<t.start;
 }
};
tim t[31];
tim ans[31];
int num;
int A,B,N;
int main()
{
 int a,b;
 char c;
 while(scanf("%d%d%d",&A,&B,&N)!=EOF)
 {  
  A*=60, B*=60; 
  num=0;
  bool flag=true;  
  memset(t,0,sizeof(t));
  memset(ans,0,sizeof(ans));
  int sh,sm,eh,em;
  for(int i=0;i<N;i++)
  {
   scanf("%d:%d-%d:%d",&sh,&sm,&eh,&em);
   t[i].start=sh*60+sm;
   t[i].end=eh*60+em;
   if(t[i].start>t[i].end) t[i].end+=24*60; 
   if(t[i].end-t[i].start>B)
   {
    flag=false;
    break;
   }
  }
  sort(t,t+N); 
  tim last;
  last.start=t[0].start;
  last.end=t[0].end;
  for(int i=1;i<N;i++)
  {
   int tmp=t[i].start-last.end-1;
   if(tmp>=A)
   {   
    ans[num].start=last.end+1;
    ans[num].end=t[i].start-1;
    last=t[i]; 
    num++;
   }
   else
   { 
    last.end=t[i].end;
    if(last.end-last.start+1>B)
    { 
     flag=false;
     break;
    }    
   }
  } 
  if(!flag)
  {
   cout<<"No"<<endl;
   continue; 
  } 
  if(t[0].start+24*60-last.end-1>=A)
  { 
   ans[num].start=(last.end+1)%(60*24);
   ans[num].end=(t[0].start+60*24-1)%(60*24); 
   num++; 
  }
  else if(num==0||(ans[0].start-1+60*24)%(60*24)-last.start+1>B)
  { 
   cout<<"No"<<endl;
   continue;
  }
  cout<<"Yes"<<endl;
  cout<<num<<endl;
  int th1,th2,tm1,tm2; 
  for(int i=0;i<num;i++)
  {
   th1=(ans[i].start%(24*60))/60;
   th2=(ans[i].end%(24*60))/60;
   tm1=ans[i].start%(24*60)%60;
   tm2=ans[i].end%(24*60)%60;
   printf("%02d:%02d-%02d:%02d\n",th1,tm1,th2,tm2);
  }
 }
 return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章