题目:Extraordinarily Tired Students
题意:
一个班上有n个学生,每个学生都用(a,b,c)描述。
a指一个周期内学生醒着的时间;b指睡觉的时间。
一个学生在睡觉前会查看班上有几人在睡觉,如果睡觉的人数比班级人数一半要多(认为他自己醒着),他就会睡觉;否则,他就会再听a分钟课,重复该步骤。
c表示初始状时学生处于周期的哪一个状态,比如周期为:awaken sleeping sleeping sleeping sleeping ,c=3,那么第一格周期为:sleeping sleeping sleeping。
要求求出所有学生都醒着的时间。
思路:
模拟题。
bool cnd[]代表学生是否醒着,false指睡着了,true指醒着。
int lst[]代表学生处于醒着/睡着的第几分钟。
判断是否死循环时,一定要是当前时间和前面的某一个时间的cnd,lst完全相同时才是死循环。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
struct Student {
int a,b,c;
};
int n;
Student student[15];
bool cnd[15][10005]= {0};
int lst[15][10005]= {0};
void init() {
for(int i=1; i<=n; i++) {
scanf("%d%d%d",&student[i].a,&student[i].b,&student[i].c);
}
memset(cnd,false,sizeof(cnd));
memset(lst,0,sizeof(lst));
for(int i=1; i<=n; i++) {
if(student[i].c<=student[i].a) lst[i][1]=student[i].c,cnd[i][1]=true;
else lst[i][1]=student[i].c-student[i].a,cnd[i][1]=false;
}
}
bool Sleep(int t) {
int sum=0;
for(int i=1; i<=n; i++) {
if(cnd[i][t]==false) sum++;
}
return sum>n/2?true:false;
}
void Make(int t) {
for(int i=1; i<=n; i++) {
if(cnd[i][t-1]==true) {
if(lst[i][t-1]==student[i].a) {
if(Sleep(t-1)) cnd[i][t]=false;
else cnd[i][t]=true;
lst[i][t]=1;
} else {
cnd[i][t]=true;
lst[i][t]=lst[i][t-1]+1;
}
} else {
if(lst[i][t-1]==student[i].b) {
cnd[i][t]=true;
lst[i][t]=1;
} else {
cnd[i][t]=false;
lst[i][t]=lst[i][t-1]+1;
}
}
}
}
int judge(int t) {
bool F=true;
for(int i=1;i<=n;i++){
if(cnd[i][t]==false){
F=false;
break;
}
}
if(F==true) return 1;
for(int j=1; j<t; j++) {
bool flag=true;
for(int i=1; i<=n; i++) {
if(lst[i][j]!=lst[i][t]||cnd[i][j]!=cnd[i][t]) {
flag=false;
break;
}
}
if(flag==true) return -1;
}
return 0;
}
int main() {
int T=0;
while(scanf("%d",&n)==1&&n!=0) {
printf("Case %d: ",++T);
init();
int t=1;
while(true) {
int J=judge(t);
if(J==-1) {
printf("-1\n");
break;
}
if(J==1) {
printf("%d\n",t);
break;
}
Make(++t);
}
}
return 0;
}