week14-猫咪睡觉问题

题目

在这里插入图片描述

分析

1、用一个结构体记录状态时间段:重载<用来排序(后面要循环遍历每个看番时间段,需要有顺序)

struct Time{
	int begin, end;
	bool operator<(const Time &tm)
	{
		return begin<tm.begin;
	}
}ans[30],be[30];//ans数组记录的是符合的睡眠时间,be数组是记录清醒时间

2、循环遍历be数组(看番时间),用last记录现在遍历的清醒时间。
计算当前清醒时间段(last记录)是否满足清醒时间,不满足就不需要进行下去了,直接no;
满足的话,计算当前的看番时间段和上一次看番时间段的间隔,是否可以睡觉,如果可以,就加入到ans数组当中。
如果不可以就把当前看番时间段包括间隔也加入到last记录的清醒时间。
3、遍历完之后发现还有最后的清醒时间段和最开始的be[0]的这个间隔没有遍历到,需要最后处理一下。

注意:
这里有一些优化的点:
1、把24小时的时间换算成分钟,直接用int表示(更好表示)。
2、输入输出的优化:scanf("%d:%d-%d:%d",&h1,&m1,&h2,&m2);和printf("%02d:%02d-%02d:%02d\n",h1,m1,h2,m2);直接表明格式了

代码

#include <iostream>
#include <algorithm>
using namespace std;
const int all=24*60;
int a,b,n;//a是睡觉时间,b是空闲时间
struct Time{
	int begin, end;
	bool operator<(const Time &tm)
	{
		return begin<tm.begin;
	}
}ans[30],be[30];//be数组是记录清醒时间
int num;
void solve(){
	bool flag=true;sort(be,be+n);//flag记录的是是否可以安排好睡眠时间
	num=-1;
	Time last;last.begin=be[0].begin;last.end=be[0].end;//记录当前正在遍历的清醒时间段
	for(int i=1;i<n;i++){
		if(last.end-last.begin+1>b*60){//不能超过空闲时间
			flag=false;break;
		}
		int temp=be[i].begin-be[i-1].end-1;//中间的睡眠时间
		if(temp>=a*60){//中间的睡眠时间超过了睡眠时间(符合)
			ans[++num].begin=be[i-1].end+1;//把这个符合睡觉的时间记录到ans数组当中
			ans[num].end=be[i].begin-1;
			last.begin=be[i].begin;last.end=be[i].end;//更新正在遍历的清醒时间
		}
		else
			last.end=be[i].end;//如果两个清醒中间时间段不能入睡,那么清醒时间段的结束加长到第二个清醒时间短末尾
	}
	if((last.end-last.begin+1)>b*60)//最后判断清醒的时间是否满足满足条件
		flag=false;
	if(flag)//n-1到0这个时间段没有处理
	{
		if(be[0].begin+all-last.end-1>=a*60)//最后清醒的时间段和最开始清醒的时间段的处理,如果符合睡眠
		{
			ans[++num].begin=(last.end+1)%all;
			ans[num].end=(be[0].begin-1+all)%all;
		}
		else if(num!=-1)//如果不符合睡眠,加入最后清醒时间看是否符合
		{
			int temp=(ans[0].begin-1+all)-last.begin+1;//计算清醒时间
			if(temp>b*60)flag=false;//不符合清醒时间就令flag=false
		}
	}
	if(!flag||num==-1)
		printf("No\n");
	else
	{
		int h1,h2,m1,m2;
		printf("Yes\n");
		printf("%d\n",num+1);
		for(int i=0;i<=num;i++)
		{
			h1=((ans[i].begin%all)/60);
			m1=ans[i].begin%all%60;
			h2=(ans[i].end%all)/60;
			m2=ans[i].end%all%60;
			printf("%02d:%02d-%02d:%02d\n",h1,m1,h2,m2);
		}
	}
}
int main()
{
	int h1,h2,m1,m2;
	while(scanf("%d%d%d",&a,&b,&n)!=EOF)
	{
		for(int i=0;i<n;i++)
		{
			scanf("%d:%d-%d:%d",&h1,&m1,&h2,&m2);
			be[i].begin=h1*60+m1;
			be[i].end=h2*60+m2;
			if(be[i].end<be[i].begin)be[i].end+=all;
		}
		solve();
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值