题目链接:POJ-1835
题目大意:
宇航员在太空中行走,给定一个三维坐标系(x,y,z轴的正方向标号分别为0,1,2,负方向标号分别为3,4,5),他的起始位置为原点,面向X轴正方向(标号为0)。然后给你n中操作,格式为 X Y ,X为相对位置上的转向的方向(forward-向前,back-向后,left-向左,right向右,down-向下,up-向上) ,Y为转向后向面对着的方向移动的距离。求n种操作的绝对坐标和绝对方向。个人对本题坐标和方向的理解:绝对坐标为宇航员最终相对起点即原点的坐标,绝对方向为最终面向的坐标轴方向,相对方向为宇航员以本身面向的方向为前,左右手分别为左右方向,其余同理。
解题思路:
因为题目要你求最终的坐标和面向的方向,所以一开始看的时候就很容易想到用几个变量去记录他每次移动后的坐标和方向,但是一开始我不知道要用几个变量来记录,我就根据题目的要求只用了四个变量,坐标x,y,z和绝对方向forward,然后我就尝试着去模拟每次移动后坐标和方向怎么变化,最后发现这样很难模拟,因为只知道forward的方向而不知道左右和上下的方向,就不能确定转向后他的foward应该怎样变,这个可以空间想象下应该不难发现,比如forward为0,此时他的up方向就有四种可能(1,2,4,5),而每种可能转向后的变换都不一样,所以只记录一个是不能确定的!
现在就换一种想法想想,怎样才能知道每次转向后他的forward应该怎样变,其实不难发现六个方向中只有三个方向是有用的左或右,上或下,前或后,应为知道其中的一个就知道他的反方向是那个,这个可以从题目中推出来,每个绝对方向的反方向为(x+3)%6 ,所以说到这里应该就知道怎么做了,用六个变量记录,坐标(x,y,z)和三个方向forward,left,up。然后就不难推出转向后三个方向怎么变化,不管绝对坐标在哪里,每次绝对方向的变化只和转换的方向有关,我这里举个例子:比如向左转,up不变,forward变为原来的left,left变为原来(forward+3)%6即foward的反方向(当然也可以打个表表示每个方向的反方向,我是这么做的)。其余都不难推出来。到此解题思路就说完了!
AC代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<string>
#include<cmath>
using namespace std;
int h[6]={3,4,5,0,1,2};
int main(){
int t;
cin>>t;
while(t--){
int Up = 2,Forward = 0,left = 4,right = 1;
int T,x1 = 0,y1 = 0,z1 = 0;
scanf("%d",&T);
while(T--){
char s[10];
int mm;
scanf("%s%d",s,&mm);
if(s[0]=='l'){
int x=Forward;
Forward=left;
right=x;
left=h[x];
}
else if(s[0]=='r'){
int x=Forward;
Forward = right;
left=x;
right=h[x];
}
else if(s[0]=='u'){
int x=Up,y=Forward;
Up=h[y];
Forward=x;
}
else if(s[0]=='d'){
int x=Up,y=Forward;
Up=y;
Forward=h[x];
}
else if(s[0]=='b'){
Forward=h[Forward];
swap(right,left);
}
if(Forward==0)x1+=mm;
else if(Forward==1)y1+=mm;
else if(Forward==2)z1+=mm;
else if(Forward==3)x1-=mm;
else if(Forward==4)y1-=mm;
else if(Forward==5)z1-=mm;
}
printf("%d %d %d %d\n",x1,y1,z1,Forward);
}
}