程序设计思维与实践 Week14 模拟 A 猫睡觉问题

题目描述:

众所周知,TT家里有一只魔法喵。这只喵十分嗜睡。一睡就没有白天黑夜。喵喵一天可以睡多次!!每次想睡多久就睡多久╭(╯^╰)╮

喵睡觉的时段是连续的,即一旦喵喵开始睡觉了,就不能被打扰,不然喵会咬人哒[○・`Д´・ ○]

可以假设喵喵必须要睡眠连续不少于 A 个小时,即一旦喵喵开始睡觉了,至少连续 A 个小时内(即A*60分钟内)不能被打扰!

现在你知道喵喵很嗜睡了,它一天的时长都在吃、喝、拉、撒、睡,换句话说要么睡要么醒着滴!

众所周知,这只魔法喵很懒,和TT一样懒,它不能连续活动超过 B 个小时。

猫主子是不用工作不用写代码滴,十分舒适,所以,它是想睡就睡滴。

但是,现在猫主子有一件感兴趣的事,就是上BiliBili网站看的新番。

新番的播放时间它已经贴在床头啦(每天都用同一张时间表哦),这段时间它必须醒着!!

作为一只喵喵,它认为安排时间是很麻烦的事情,现在请你帮它安排睡觉的时间段。

input:

多组数据,多组数据,多组数据哦,每组数据的格式如下:

第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 分钟。
不保证输入的新番时间表有序。

output:

我们知道,时间管理是一项很难的活,所以你可能没有办法安排的那么好,使得这个时间段满足喵喵的要求,即每次睡必须时间连续且不少于 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 不太一样,也可能是对的,它有一个判题程序来判定你的答案(当然,你对你自己的答案肯定也能肉眼判断)

思路:

本题的难点在于跨夜的番的时间的处理,联系以前练习过循环数组,这里对于将时间段*2,即:将一天延伸至两天。例如,今天的某个时间段在第二天的相同时间也会有相同。

对于输入的处理:使用字符串读入时间,并且将所有的时间处理成分钟,例如:00:00为第1分钟。01:00为第61分钟。由于时间段做了扩展处理,则第一天24点(同时为第二天0点)所对应的分钟为:24*60=1440

输入之后,对于每个番可处理出时长,单位为分钟。首先扫描一遍,若某个番的时长>B*60,则直接输出no。

对每个番按照起始时间排序,从头遍历每个番。根据贪心的思想:如果能睡,则尽量睡的时间长一些,这是一定没有问题的。因此,如果两个番之间的时间间隔>=A*60,则直接整个间隔都去睡觉。如果时间间隔<A*60,即没法睡觉,这段时间间隔是醒着的,并且下一段番的播放时间也是醒着,此时就需要判断从上一次醒来的时间到下一段番的时间长度是不是<=B*60,如果超出了,结果也是no。

一天中睡觉的时间段的数量为k,当k==0时,即使A==24,答案也是no,因为k==0代表一天不睡觉,那么第二天、第三天肯定也不睡觉,而这段时间显然超过了24小时。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int ta,tb,n;
string s;
vector<string> v;
struct node
{
	int u;
	int v;
	int w;
	bool operator <(const node o)const
	{
		return u<o.u;
	}
}f[50];
void init(int i)
{
	int h=s[0]-48;
	h=h*10+s[1]-48;
	int m=s[3]-48;
	m=m*10+s[4]-48;
	f[i].u=h*60+m+1;
	h=s[6]-48;
	h=h*10+s[7]-48;
	m=s[9]-48;
	m=m*10+s[10]-48;
	f[i].v=h*60+m+1;
	if(f[i].v<f[i].u)
	f[i].v+=24*60;
	f[i].w=f[i].v-f[i].u+1; 
}
void get_s(int s,int p)
{
	s--;p--;
	string t;
	t.clear();
	int tmp1=s/60;
	int tmp2=s%60;
	if(tmp1>23) tmp1-=24;
	char c=(tmp1/10)+48;t+=c;
	c=tmp1%10+48;t+=c;t+=':';
	c=(tmp2/10)+48;t+=c;
	c=tmp2%10+48;t+=c;t+='-';
	
	tmp1=p/60;
	tmp2=p%60;
	if(tmp1>23) tmp1-=24;
	c=(tmp1/10)+48;t+=c;
	c=tmp1%10+48;t+=c;t+=':';
	c=(tmp2/10)+48;t+=c;
	c=tmp2%10+48;t+=c;
	
	v.push_back(t);
}
int main()
{
	while(scanf("%d%d%d",&ta,&tb,&n)!=EOF)
	{
		v.clear();
		ta*=60;tb*=60;
		int maxx=0;
		for(int i=1;i<=n;i++)
		{
			cin>>s;
			init(i);
			f[i+n].u=f[i].u+24*60;
			f[i+n].v=f[i].v+24*60;
			f[i+n].w=f[i].w;
			maxx=max(maxx,f[i].w);
		}
		if(maxx>tb)
		{
			cout<<"No"<<endl;
			continue;
		}
		sort(f+1,f+n*2+1);
		int i=2,las=f[1].u,last=f[1].v+1,next;
		bool flag=0;
		while(i<=2*n)
		{
			if(f[i].u-last>=ta)//睡觉 
			{
				get_s(last,f[i].u-1);
				last=f[i].v+1;las=f[i].u;
				i++;
			}
			else if(f[i].u-last<ta)//不能睡觉,时间不够 
			{
				if(f[i].v-las+1>tb)
				{
					cout<<"No"<<endl;
					flag=1;break;
				}
				else
				{
					last=f[i].v+1;
					i++;
				}
			}
		}
		if(flag) continue;
		/*for(int i=1;i<=2*n;i++)
		{
			cout<<f[i].u<<" "<<f[i].v<<" "<<f[i].w<<endl;
			//string tmp=get_s(f[i].u,f[i].v);
			//cout<<tmp<<endl;
		}*/
		if(v.size()==0)
		{
			cout<<"No"<<endl;
			continue;
		}
		sort(v.begin(),v.end());
		v.erase(unique(v.begin(), v.end()), v.end());
		cout<<"Yes"<<endl<<v.size()<<endl;
		for(int i=0;i<v.size();i++)
		cout<<v[i]<<endl;
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/cax1165/article/details/106291498