#include <stdio.h>
const int mn = 100;
int now = 1,flag = 0,high = 10,to = -1;//now表示现在的楼层 high最高楼层,to移动的目标楼层
//flag 表示当前的运行方向,1 向上,-1向下,0闲着
bool up[mn],down[mn],toward[mn];//外部诉求几层要上还是要下,内部诉求想去几层
//void check(){
// if(nowweight > maxweight) printf("overweight\n");
//} 借助传感器实现,超重给警报
void outread(){//电梯外部按电梯
printf("out:\n");
int num,order;//所在楼层,想去的方向
scanf("%d%d",&num,&order);
if(num != -1&& flag == 0){//电梯闲置,先按电梯,那我就先往谁移动
to = num;
if(now == num) flag = order;
else if(now >= num) flag = -1;
else flag = 1;
}
while(num != -1){//-1作为输入结束标志
//相应楼层有诉求,order 1向上,-1向下
if(order == 1) up[num] = true;
if(order == -1) down[num] = true;
scanf("%d%d",&num,&order);
}
}
void inread(){//电梯内部按电梯只选择往几楼去,并没办法选择方向
printf("in:\n");
int num;
while(scanf("%d",&num)&&num != -1){
toward[num] = true;
}
}
int find(int nowto){//找沿着当前方向需要到达最远的楼层
if(nowto == 1){
for(int i = high;i > now&&i > 0;i --){
if(toward[i] || up[i] ||down[i]){
return i;
}
}
}
else if(nowto == -1){
for(int i = 1;i < now && i <= high;i ++){
if(toward[i] || down[i]||up[i]){
return i;
}
}
}
return -1;//没有找到返回-1,方便后面的判断
}
void move(int nowto,int cur){//本次移动的方向,起始楼层
if(flag == 1){//向上移动
for(int i = cur + 1;i <= to;i ++){//从下一层开始,到目标楼层
if(find(1)== -1 &&find(-1) == -1) return ;
now = i;
printf("now will arrive %d,moving up\n",i);//每楼层输出方向
if(up[i]){
printf("open the door at %d\n",i);//当前楼层有诉求,就开门
up[i] = false;
toward[i] = false;
inread(); //每次到有诉求的楼层,都会有人上来在内部按电梯
}
else{
if(toward[i]){ //如果只是有人要到这个电梯的话,那就只是下,就没人按电梯,不用inread
printf("open the door at %d\n",i);//当前楼层有下的,也要开门
toward[i] = false;
}
}
to = find(flag);//因为过程中会有人上,可能要到达当前方向更远的楼层,因此to要不断进行更新
if(to == -1){//比如说当前在1楼,结果8楼有人下来
//我肯定要到8楼先,肯定是向上,但是到了8楼结果不再向上,我这时候就要及时改变方向运行
if(down[now]){
down[now] = false;
flag = -1;
printf("open the door at %d\n",now);
inread();
to = find(flag);
if(to == -1){//避免有人按错明明要在9楼下去,结果电梯开门后他按了10楼的电梯
flag = 1;
to = find(flag);
}
}
}
}
}
if(flag == -1){//对称,同上
for(int i = cur - 1;i >= to;i --){
if(find(1)== -1 &&find(-1) == -1) return ;
now = i;
printf("now will arrive %d,moving down\n",i);
if(down[i]){
printf("open the door at %d\n",i);
down[i] = false;
toward[i] = false;
inread();
}
else{
if(toward[i]){
printf("open the door at %d\n",i);
toward[i] = false;
}
}
to = find(flag);
if(to == -1){
if(up[now]){
up[now] = false;
flag = 1;
printf("open the door at %d\n",now);
inread();
to = find(flag);
if(to == -1){
flag = -1;
to = find(flag);
}
}
}
}
}
}
void solve(){//从电梯运行开始,到当前批次运行结束
to = -1;
if(flag == 0){
printf("now is unoccupied at %d\n",now);
outread();
if(to == now){//如果电梯当前楼层最先有诉求,直接开门
printf("open the door at %d\n",now);
inread();
}
while(flag){//一直到当前批次进行结束
move(flag,now);
if(find(1) == -1 && find(-1) == -1){
flag = 0;//两个方向都找不到任务,直接结束这一轮
return;
}
//否则一定是有一个方向有任务
to = find(flag);
if(to == -1){
flag *= -1;
to = find(flag);
move(flag,now);
}
else{
move(flag,now);
}
}
}
}
int main(){
while(1){
solve();
}
return 0;
}
使用说明:
屏幕中出现 now is unoccupied at num
表示电梯当前在num层停着没人用
出现 out 就表示读入外部按电梯的指令,每条指令分为两个数字,num和order
num表示几楼在按电梯,order 为1表示它要上去,order为-1表示它要下去 最后以 -1 -1 作为读入结束的标志
出现in表示电梯开门之后有人在内部按电梯,读入内部按电梯的指令,每条指令一个数字,表示想去几楼 以-1 作为读入的标志
指令读入由传感器实现,我们便默认所有指令都是合法的
同时检测质量,判断当前们是否有阻挡能否关门也是由传感器实现,我们约定,不超重,均能正常关,我们只是模拟电梯的运行选择