pku1211 Traffic Lights 简单模拟+堆优化

pku1211 Traffic Lights 简单模拟+堆优化

题目说的很乱,我整理一下
所有灯都按绿、橙、红的顺序变化,绿色持续t-5秒,橙色持续5秒,红色持续t秒,第0时刻所有灯都是刚刚变绿。求所有灯再一次变绿的最早时刻

解法:
有一点要明确,所求的最早时刻肯定是所有灯中其中一盏刚刚变绿,否则我们能够找到一个更早的时刻所有灯都是绿的。那么只要枚举所有灯的开始时间,然后再判断此时刻所有灯都是绿色即可。
由于题目要求时刻小于5小时,即使暴力枚举也不过3600*5,再加上判断复杂度,总复杂度为360000*5,应该也能过
当然,可以用堆来优化,这样能够将最坏复杂度至少降低一半

代码:
 1 # include  < cstdio >
 2 # include  < queue >
 3 # include  < cstring >
 4 using   namespace  std;
 5 struct  node
 6 {
 7   int i,t;
 8   bool operator<(const node &b) const
 9   {
10      return t>b.t;
11   }

12   node(int id,int time):i(id),t(time){}
13}
;
14 int  loop[ 101 ],c,start;
15 priority_queue < node >  q;
16 bool  chk( int  t)
17 {
18   for(int i=0;i<c;i++)
19     if(t%(2*loop[i])>=loop[i]-5return false;
20   return true
21}

22 void  print( int  t)
23 {
24   printf("%s%d:%s%d:%s%d\n",t/3600<10?"0":"",t/3600,(t%3600)/60<10?"0":"",(t%3600)/60,(t%3600)%60<10?"0":"",(t%3600)%60); 
25}

26 int  main()
27 {
28   while(true)
29   {
30      c=0;
31      while(!q.empty()) q.pop();
32      scanf("%d",&loop[c++]);
33      if(!loop[0])
34      {
35        scanf("%d%d",&loop[1],&loop[2]);
36        break;
37      }

38      else
39      {
40          int flag=0;
41          while(loop[c-1])
42             scanf("%d",&loop[c++]);
43          c--;
44          start=0xfffffff;
45          for(int i=0;i<c;i++)
46            if(loop[i]-5<start) start=loop[i]-5;
47          start=0;
48          for(int i=0;i<c;i++)
49            if(2*loop[i]-start<=3600*5) q.push(node(i,2*loop[i]));
50          while(!q.empty()&&!flag)
51          {
52             node top=q.top();
53             q.pop();
54             if(chk(top.t)) flag=top.t;
55             else
56             {
57                 top.t+=2*loop[top.i];
58                 if(top.t-start<=5*3600) q.push(top);
59             }

60          }

61          if(flag) print(flag-start);
62          else printf("Signals fail to synchronise in 5 hours\n");
63      }

64   }
   
65   return 0;
66}

67
68

你可能感兴趣的:(pku1211 Traffic Lights 简单模拟+堆优化)