No.9.2 在立体表面上移动的机器人

一、题目描述

Lucy开发了一款刷墙机器人,可以在水平和竖直的平面上运动。

这款机器人支持3个指令操作:

1: 向前移动1个单位,如果当前是一个平面的边缘,则会走到另一个平面上相邻的位置;2: 右转;3: 左转

No.9.2 在立体表面上移动的机器人

 

 2.只能在上面的五个面上移动

No.9.2 在立体表面上移动的机器人

 

3.给定:
第一行:立方体边长N(<=50)

第二行:起始坐标(一定是正面1上)和方向(上:0,右:1,下:2,左:3)

第三行:命令数(<=1000)

第四行:指令集

 

二、结果输出

执行完指令后,机器人所在的平面编号

 

三、问题模拟

有几个问题点:

1.当一个方向不定的时候,所谓的左转和右转怎么实现:在每个面上,自定义方向时,一定要按(上:0,右:1,下:2,左:3)的顺时针方向,这样左转==索引-1,右转==索引+1;

2.从一个面转到另一个面时,不仅是坐标变了,移动方向也会因为平面的不同而不同,用枚举法;

3.面的切换,是根据每个面的坐标范围

4.注意下坐标轴 x,y,z 的方向,拿第一个指令集作为例子:

No.9.2 在立体表面上移动的机器人

 

 

 

#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;
}

上一篇:ps


下一篇:Laravel 优雅解决接口数据带T Z格式问题(日期序列化)