Uva 12108 Extraordinarily Tired Students
题意:
课堂上有n个学生(n<=10)。每个学生都有一个“清醒-睡眠”周期。其中第i个学生醒 ai 分钟后睡
bi 分钟,然后重复(1<=ai,bi<=5),初始时第i个学生处在他的周期的第 ci 分钟。每个学生在临
睡前会察看全班睡觉人数是否严格大于清醒人数,只有这个条件满足时才睡觉,否则就坚持听课 ai
分钟后再次检查这个条件。问经过多长时间后全班都清醒。
思路:
用优先队列记录每次要更改的时间和对应要更改状态的学生编号,按要更改的时间从小到大排序。
cnt记录当前睡觉的人数。
这里要注意的是:由于临睡前要判断,但是可能队列中存在同一时刻x个同学睡y个同学醒的情况,
如果先是处理了醒的同学,然后是在cnt上直接修改的,那么睡的人就减少了,就可能出现本来是
可以睡的,由于先处理了醒的人,所以这个判断不准确了,因为判断时用的人数应该是这一秒没做
任何处理时的人数。处理应该是同时做出的,故设置一个局部变量sum来记录这一秒的人数变动。
当进入下一个修改的时刻才把sum在cnt上做累加。
还有就是 如何判断不存在 “全部都清醒的时刻” 呢 ?
直观感受就是睡觉的人数没有减少过。
我是 记录每次更新的sum==0的次数,超过了10000次就自动跳出循环。这样好像不太严谨。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cctype> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 #include<set> 12 #define eps 10e-6 13 14 using namespace std; 15 16 typedef long long ll; 17 18 int a[12],b[12],c[12]; 19 bool sleep[12]; 20 priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > > q; 21 22 int main() 23 { 24 int n,cas=1; 25 while(~scanf("%d",&n) && n) 26 { 27 int cnt = 0; //睡的人数 28 memset(sleep,0,sizeof(sleep)); 29 while(!q.empty()) 30 q.pop(); 31 int ans = -1; 32 33 for(int i=0;i<n;i++) 34 { 35 scanf("%d%d%d",&a[i],&b[i],&c[i]); 36 // c[i] = c[i]%(a[i]+b[i]); 37 if(c[i]>a[i]) 38 { 39 cnt++; 40 sleep[i]=true; 41 q.push(make_pair(a[i]+b[i]-c[i]+2,i)); 42 } 43 else q.push(make_pair(a[i]-c[i]+2,i)); 44 } 45 int pre = 0,sum = 0; 46 int fun = 0; 47 while(!q.empty()) 48 { 49 pair<int,int> now = q.top(); 50 q.pop(); 51 int id = now.second; 52 int t = now.first; 53 54 if(t>pre) 55 { 56 cnt += sum; 57 if(sum==0) fun++; 58 if(fun>=10000) break; 59 sum = 0; 60 if(cnt==0) 61 { 62 ans = pre; 63 break; 64 } 65 pre = t; 66 } 67 68 if(sleep[id]) 69 { 70 sleep[id] = false; 71 sum--; 72 q.push(make_pair(t+a[id],id)); 73 } 74 else 75 { 76 if(cnt<=n-cnt) 77 { 78 q.push(make_pair(t+a[id],id)); 79 continue; 80 } 81 sleep[id] = true; 82 sum++; 83 q.push(make_pair(t+b[id],id)); 84 } 85 } 86 printf("Case %d: %d\n",cas++,ans); 87 } 88 return 0; 89 }