12108 - Extraordinarily Tired Students(特别困的学生)

题目:

When a student is too tired, he can’t help sleeping in class, even if his favorite teacher is right here in front of him. Imagine you have a class of extraordinarily tired students, how long do you have to wait, before all the students are listening to you and won’t sleep any more? In order to complete this task, you need to understand how students behave. When a student is awaken, he struggles for a minutes listening to the teacher (after all, it’s too bad to sleep all the time). After that, he counts the number of awaken and sleeping students (including himself). If there are strictly more sleeping students than awaken students, he sleeps for b minutes. Otherwise, he struggles for another a minutes, because he knew that when there is only very few sleeping students, there is a big chance for them to be punished! Note that a student counts the number of sleeping students only when he wants to sleep again. Now that you understand each student could be described by two integers a and b, the length of awaken and sleeping period. If there are always more sleeping students, these two periods continue again and again. We combine an awaken period with a sleeping period after it, and call the combined period an awaken-sleeping period. For example, a student with a = 1 and b = 4 has an awaken-sleeping period of awaken-sleeping-sleeping-sleeping-sleeping. In this problem, we need another parameter c (1 ≤ c ≤ a + b) to describe a student’s initial condition: the initial position in his awaken-sleeping period. The 1st and 2nd position of the period discussed above are awaken and sleeping, respectively. Now we use a triple (a, b, c) to describe a student. Suppose there are three students (2, 4, 1), (1, 5, 2) and (1, 4, 3), all the students will be awaken at time 18. The details are shown in the table below.

题目大意:

每个学生有一个“睡眠-清醒” 周期, 第i个学生醒Ai分钟睡 Bi分钟, 初始处在他的周期的第Ci分钟, 临睡时会查看全班睡眠人数是否>清醒人数, 是则进入睡眠周期, 不然保持清醒Ai分钟, 问多久后全部学生都清醒。

分析:

题目求的是清醒人数, 那么我们可以把清醒人数设为一个变量, 设一个足够长的时间轴作为循环, 当清醒人数为N时跳出循环, 否则到了时间轴尾就输出-1。 题目给定的Ci其实很好的帮我们处理了“当前时间的问题”, 可以这样想, 时间轴每一点都进行ci的判断, <ai 则清醒人数++(清醒人数每一点初始化为0), 然后如果ci == ai 就判断人数, 如果不符合将ci回归到1, 同时当ci = ai + bi时也要回归到1

代码:

#include <stdio.h>
#include <string.h>
#define maxn 15
struct STUDENT {
	int A;//清醒A分钟
	int B;//睡B分钟
	int C;//当前处于的周期时间C分钟
	int D;//周期总时间
	int is_sleep;//当前时间是不是睡着
}st[maxn];
int cases = 0, n;
int main()
{
	while (scanf("%d", &n) && n)
	{
		int ALL = 1;//所有学生的醒睡总周期
		int awake = 0, sleep = 0;//全班清醒人数和睡觉人数
		for (int i = 0;i < n;i++)
		{
			scanf("%d%d%d", &st[i].A, &st[i].B, &st[i].C);
			st[i].D = st[i].A + st[i].B;
			if (st[i].C <= st[i].A)
			{
				st[i].is_sleep = 0;
				awake++;
			}
			else
			{
				st[i].is_sleep = 1;
				sleep++;
			}
			ALL *= st[i].D;
		}
		int time;//当前时间
		int flag=0;//标记是否存在全班都清醒的时刻
		for (time = 1;time <= ALL;time++)//只需要判断从初始回到初始这个时间段的情况
		{
			if (awake == n)
			{
				flag = 1;
				break;
			}
			int pre_sleep = sleep;//pre_sleep是上一时刻睡觉人数
			int pre_awake = awake;//pre_awake是上一时刻清醒人数
			for (int i = 0;i < n;i++)
			{
				st[i].C++;//下面就在i位学生周期的C时刻该学生的状态进行讨论
				//只有两种变化(醒->睡和睡->醒)时才需更新状态,其余情况只需C叠加
				if (st[i].C == (st[i].D + 1))//睡->醒
				{
					st[i].C = 1;
					st[i].is_sleep = 0;
					sleep--;
					awake++;
				}
				else if (st[i].C == (st[i].A + 1))//醒->睡
				{
					if (pre_sleep > pre_awake)
					{ //这点很重要!sleep和awake是变化当前状态,而需要判断的实际上是上一时刻
						st[i].is_sleep = 1;
						sleep++;
						awake--;
					}
					else st[i].C = 1;
				}
			}
		}
		if (flag) printf("Case %d: %d\n", ++cases, time);
		else printf("Case %d: %d\n", ++cases, -1);
	}
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值