一、题目描述
Lucy开发了一款刷墙机器人,可以在水平和竖直的平面上运动。
这款机器人支持3个指令操作:
1: 向前移动1个单位,如果当前是一个平面的边缘,则会走到另一个平面上相邻的位置;2: 右转;3: 左转
2.只能在上面的五个面上移动
3.给定:
第一行:立方体边长N(<=50)
第二行:起始坐标(一定是正面1上)和方向(上:0,右:1,下:2,左:3)
第三行:命令数(<=1000)
第四行:指令集
二、结果输出
执行完指令后,机器人所在的平面编号
三、问题模拟
有几个问题点:
1.当一个方向不定的时候,所谓的左转和右转怎么实现:在每个面上,自定义方向时,一定要按(上:0,右:1,下:2,左:3)的顺时针方向,这样左转==索引-1,右转==索引+1;
2.从一个面转到另一个面时,不仅是坐标变了,移动方向也会因为平面的不同而不同,用枚举法;
3.面的切换,是根据每个面的坐标范围
4.注意下坐标轴 x,y,z 的方向,拿第一个指令集作为例子:
#include<stdio.h>
int T,N,p,q,h=0,K,M=1; //p,q,h == x,y,z 三维坐标,M表示面坐标
int fangxiang[5][4][3] ={
{{0,-1,0},{1,0,0},{0,1,0},{-1,0,0}}, // 1
{{0,-1,0},{-1,0,0},{0,1,0},{1,0,0}}, // 2
{{0,-1,0},{0,0,1},{0,1,0},{0,0,-1}}, // 3
{{0,-1,0},{0,0,-1},{0,1,0},{0,0,1}}, // 4
{{0,0,1},{1,0,0},{0,0,-1},{-1,0,0}} // 5
};
typedef struct datasave{
int tx; int ty; int tz; //三维坐标
int zx; int zy; int zz; //方向向量
} ;
datasave change_mian(int n,int m,int x,int y,int z,int zx,int zy,int zz){ //枚举:面切换时,坐标与移动方向的变化
datasave test;
int b=0; //方向向量的索引
if(n==1 && m==5) {y=0;z=1;b=0;}
if(n==5 && m==1) {y=1;z=0;b=2;}
if(n==2 && m==5) {y=0;z=N;b=2;}
if(n==5 && m==2) {y=1;z=N+1;b=2;}
if(n==3 && m==5) {x=N;y=0;b=3;}
if(n==5 && m==3) {x=N+1;y=1;b=2;}
if(n==4 && m==5) {x=1;y=0;b=1;}
if(n==5 && m==4) {x=0;y=1;b=2;}
if(n==1 && m==3) {x=N+1;z=1;b=1;}
if(n==3 && m==1) {x=N;z=0;b=3;}
if(n==2 && m==3) {x=N+1;z=N;b=3;}
if(n==3 && m==2) {x=N;z=N+1;b=1;}
if(n==1 && m==4) {x=0;z=1;b=3;}
if(n==4 && m==1) {x=1;z=0;b=1;}
if(n==2 && m==4) {x=0;z=N;b=1;}
if(n==4 && m==2) {x=1;z=N+1;b=3;}
test.tx=x; test.ty=y; test.tz=z;
test.zx=fangxiang[m-1][b][0];
test.zy=fangxiang[m-1][b][1];
test.zz=fangxiang[m-1][b][2];
return test;
}
int main(){
datasave tt;
int i,j,t;
int tx,ty,tz,tm,mt,tmm; //tm=当前面,mt=转换面,tmm=移动方向
int zx,zy,zz; //方向向量
int lm[1001];
scanf("%d",&T);
or(j=1;j<=T;j++)
{
scanf("%d",&N); //边长
scanf("%d %d %d",&p,&q,&t); // t==方向(0:up, 1:right, 2:down, 3:left)
scanf("%d",&K); //命令数
tx=p;ty=q;tz=h;
tm=M;mt=M;tmm=t;
for(i=1;i<=K;i++){
scanf("%d",&lm[i]);
}
for(i=1;i<=K;i++){
if(lm[i]==1){
zx=fangxiang[mt-1][tmm][0];
zy=fangxiang[mt-1][tmm][1];
zz=fangxiang[mt-1][tmm][2];
tx=tx+zx; ty=ty+zy; tz=tz+zz;
//判断边界
if(ty>N)
{
tx=tx-zx;ty=ty-zy;tz=tz-zz;
continue;
}
else{ //面切换,一定要和函数 change_mian 中,面切换导致的方向切换一致
if(tz==0 && ty==0 && tx>=1 && tx<=N){ // 1 VS 5
if(tm==1) {mt=5;tmm=0;}
if(tm==5) {mt=1;tmm=2;}
}
if(tz==N+1 && ty==0 && tx>=1 && tx<=N){ // 2 VS 5
if(tm==2) {mt=5;tmm=2;}
if(tm==5) {mt=2;tmm=2;}
}
if(tx==N+1 && ty==0 && tz>=1 && tz<=N){ // 3 VS 5
if(tm==3) {mt=5; tmm=3;}
if(tm==5) {mt=3; tmm=2;}
}
if(tx==0 && ty==0 && tz>=1 && tz<=N){ // 4 VS 5
if(tm==4) {mt=5;tmm=1;}
if(tm==5) {mt=4;tmm=2;}
}
if(tx==N+1 && tz==0 && ty>=1 && ty<=N){ // 1 VS 3
if(tm==1) {mt=3;tmm=1;}
if(tm==3) {mt=1;tmm=3;}
}
if(tx==N+1 && tz==N+1 && ty>=1 && ty<=N){ // 2 VS 3
if(tm==2) {mt=3;tmm=3;}
if(tm==3) {mt=2;tmm=1;}
}
if(tx==0 && tz==0 && ty>=1 && ty<=N){ // 1 VS 4
if(tm==1) {mt=4;tmm=3;}
if(tm==4) {mt=1;tmm=1;}
}
if(tx==0 && tz==N+1 && ty>=1 && ty<=N){ // 2 VS 4
if(tm==2) {mt=4;tmm=1;}
if(tm==4) {mt=2;tmm=3;}
}
tt=change_mian(tm,mt,tx,ty,tz,zx,zy,zz);
tm =mt;
tx=tt.tx; ty=tt.ty; tz=tt.tz;
zx=tt.zx; zy=tt.zy; zz=tt.zz;
}
}
if(lm[i]==2){
//右转==索引+1;如果索引==3,索引+1=0
if (tmm==3) tmm=0;
else tmm=tmm+1;
}
if(lm[i]==3){
//左转==索引-1;如果索引==0,索引-1=3
if(tmm==0) tmm=3;
else tmm=tmm-1;
}
}
printf("#%d %d\n",j,mt);
}
getchar();getchar();return 0;
}