课堂上有n个学生(n≤10)。每个学生都有一个“睡眠-清醒”周期,其中第i个学生醒A i 分
钟后睡B i 分钟,然后重复(1≤A i ,B i ≤5),初始时第i个学生处在他的周期的第C i 分钟。每个
学生在临睡前会察看全班睡觉人数是否严格大于清醒人数,只有这个条件满足时才睡觉,否
则就坚持听课A i 分钟后再次检查这个条件。问经过多长时间后全班都清醒。如果用(A,B,C)描
述一些学生,则图4-11中描述了3个学生(2,4,1)、(1,5,2)和(1,4,3)在每个时刻的行为。
原题比较长 总结下来大意是这样的
1 输入 n 代表有n个人 接下来是n 个a b c a表示 清醒的时间 b表示睡觉的时间 c表示现在到了哪一个时间 (a+b表示一个周期 c则表示到了这个周期那个时间点上)
2 如果有半数或者半数以上的人没有睡觉 则不会继续睡下去了(就是一直醒着不会再睡了)。
所以我们可以这样做:
我们可以的到一个思路直接那就是直接的模拟每个时刻然后判断这个时刻是否有小于一半的人在睡觉
如果有超过一半没有睡眠那么则循环到最后一个睡醒的位置输出结果
如果在进行时发现当前的状态等于最开始的状态就表示出现了周期循环,那么则无解
由此我们就可以的得到代码(转载)
#include <iostream>
#include <cstdio>
using namespace std;
struct student {
int wake;
int sleep;
int loc;
} stu[10];
int main()
{
//freopen("input.in","r",stdin);
//freopen("output.out","w",stdout);
int n;
int index=1;
while(cin>>n) {
if(n==0) break;
int start[10];
int sleep=0;
for(int i=0; i<n; i++) {
cin>>stu[i].wake>>stu[i].sleep>>stu[i].loc;
stu[i].loc--;
start[i]=stu[i].loc;
if(stu[i].loc>stu[i].wake-1)
sleep++;
}
long long time=0;
while(++time) {
bool flag=0;
if(sleep>n-sleep) flag=1;//如果睡觉的的人多
for(int i=0; i<n; i++) {
//同时处于马上要睡着的人,这时就睡着
//注意这里要判断是不是第一次,要是第一次就不进行计算
if(time == 1)break;
if(flag) {
if(stu[i].loc==stu[i].wake)//表示下一个时间段是睡眠 把睡眠数 +1
sleep++;
if(stu[i].loc==0)
sleep--;
} else {
if(stu[i].loc==stu[i].wake)
stu[i].loc=0;
else if(stu[i].loc==0)
sleep--;
}
}
bool flag2=1;
if(time==1) flag2=0;
for(int i=0; i<n; i++) {
//判断是否与开始时的状态相同
if(stu[i].loc!=start[i]) flag2=0;
//然后对每个同学所处的位置自增
stu[i].loc++;
//不过要保证在这个区间内
stu[i].loc%=(stu[i].sleep+stu[i].wake);
}
if(sleep==0)
break;
if(flag2) {
//cout<<time<<endl;
time=-1;
break;
}
//cout<<"sleep:"<<sleep<<endl;
}
cout<<"Case "<<index++<<": "<<time<<endl;
}
return 0;
}