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 }
View Code

 

posted @ 2015-10-25 16:29  fukan  阅读(758)  评论(0编辑  收藏  举报