【模拟】4331 - Elevator (08年北京赛区)
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2332
题意模拟一部电梯运行情形,运行方法与正常理解的电梯运行一致,详见题面。
比较复杂的一道模拟题,一开始感觉很容易产生错误,仔细考虑后通过将电梯状态划分成7种状态来实现程序,分别是
0:无任务的停止状态。 1、-1:移动状态(上/下)。 2、-2:带任务的停止状态(上/下)-注此时电梯门未打开。3、-3:电梯门打开的停止状态。
列出状态之后,可以发现我们只需要考虑一下情形
0:是否转移到2(无输出)
1:是否转移到2(输出停止移动)
2:转移到0(无输出) 、 转移到1(输出开始移动) 、转移到3(输出开门)
3:保持3(输出出电梯或进电梯)、转移到2(输出关门)
同时在非0状态时候,判断电梯转向。 综上,通过合理的状态预先规划使得我们程序的模拟难度大大降低,同时更不容易考虑漏。最后顺利1A,附代码:
View Code
1 //By Lin 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define Rep(i,n) for(int i = 0; i<n; i++) 6 using namespace std; 7 8 int in_que[55]; 9 int n,state,t,now; 10 struct Ask{ 11 int t,s,d; 12 bool ok; 13 void init(){ 14 scanf("%d%d%d", &t, &s, &d ); 15 ok = false; 16 } 17 friend bool cmp( const Ask &a ,const Ask &b){ 18 return a.t < b.t; 19 } 20 }data[105]; 21 22 int up_or_down(){ 23 int k = -1; 24 Rep(i,n){ 25 if ( data[i].t > t || data[i].ok ) continue; 26 if ( k == -1 ) { k = i; continue; } 27 if ( data[i].t < data[k].t ) k = i; 28 if ( data[i].t > data[k].t ) continue; 29 if ( data[i].s == now && data[k].s != now ) k = i; 30 if ( data[i].s != now && data[k].s == now ) continue; 31 if ( data[i].s > now ) k = i; 32 } 33 if ( k == -1 ) return 0; 34 if ( data[k].s != now ) return data[k].s>now?2:-2; 35 return data[k].d>now?2:-2; 36 } 37 38 int trun(){ 39 if ( state == 0 ) return 0; 40 for (int i = 1; i<=50; i++) if ( in_que[i] ) return -1; 41 Rep(i,n){ 42 if ( data[i].t > t || data[i].ok ) continue; 43 if ( data[i].s>now && state>0 || data[i].s<now && state<0 ) return -1; 44 if ( data[i].s == now && (data[i].d>now && state>0 || data[i].d<now && state<0) ) return -1; 45 } 46 return 1; 47 } 48 49 int ask(bool flag = false ){ 50 int ret = 0; 51 Rep(i,n){ 52 if ( data[i].t > t || data[i].ok ) continue; 53 if ( data[i].s == now && (data[i].d>now && state>0 || data[i].d<now && state<0) ) { 54 ret ++; 55 if ( flag ){ 56 data[i].ok = true; 57 in_que[data[i].d]++; 58 } 59 } 60 } 61 return ret; 62 } 63 64 bool over(){ 65 for (int i = 1; i<=50; i++) if ( in_que[i] ) return false; 66 Rep(i,n) if ( !data[i].ok ) return false; 67 return true; 68 } 69 int main(){ 70 int cas , tt = 0; 71 scanf("%d", &cas ); 72 while ( cas -- ){ 73 printf("Case %d:\n", ++ tt ); 74 scanf("%d%d", &now , &n ); 75 Rep(i,n) data[i].init(); 76 state = t = 0; 77 int flag; 78 79 while ( !(state == 0 && over()) ) { 80 if ( trun() == 1 ) state *= -1; 81 switch ( state ){ 82 case 0: 83 flag = up_or_down(); 84 if ( flag == 0 ) t++; 85 else state = flag; 86 break; 87 case 1: 88 case -1: 89 if ( in_que[now] || ask() ){ 90 state = state>0?2:-2; 91 printf("%02d:%02d The elevator stops at floor %d.\n", t/60,t%60,now ); 92 } 93 break; 94 case 2: 95 case -2: 96 if ( in_que[now] || ask() ){ 97 printf("%02d:%02d The elevator door is opening.\n",t/60,t%60 ); 98 t++; 99 state = state>0?3:-3; 100 } 101 else if ( trun() == -1 ){ 102 printf("%02d:%02d The elevator starts to move %s from floor %d.\n",t/60,t%60,state>0?"up":"down",now); 103 state = state>0?1:-1; 104 } 105 else state = 0; 106 break; 107 case 3: 108 case -3: 109 if ( in_que[now] ){ 110 printf("%02d:%02d %d people leave the elevator.\n", t/60,t%60,in_que[now] ); 111 in_que[now] = 0; 112 t++; 113 } 114 else if ( ask() ){ 115 printf("%02d:%02d %d people enter the elevator.\n", t/60,t%60,ask(1) ); 116 t++; 117 } 118 else { 119 printf("%02d:%02d The elevator door is closing.\n" ,t/60,t%60 ); 120 t++; 121 state = state>0?2:-2; 122 } 123 break; 124 } 125 if ( abs(state) == 1 ) { 126 t ++; 127 now += state; 128 } 129 } 130 puts(""); 131 } 132 return 0; 133 }