今天遇到一个有点好玩的算法,就是通过一系列的指令来控制机器人的行走,最后要求定位机器人的准确位置。第一次写还写错了,改了一次才正确,觉得很有意思,就记下来了。
机器人有 4种指令:
- forward x,前进 x 米。
- back x,先向后转,然后前进 x 米。
- left x,先向左转,然后前进 x 米。
- right x,先向右转,然后前进 x 米。
现在把机器人放在坐标轴原点,起始朝向为 x轴正方向。经过一系列指令以后,你能告诉蒜头君机器人的坐标位置吗。坐标轴上一个单位长度表示 1 米。
输入格式
第一行输入一个整数 n(1≤n≤100) 表示指令的个数。
接下里 n 行,每行输入形如上面的指令,其中 −1000≤x≤1000。
输出格式
输出两个整数 x,y表示机器人最后坐标。用空格隔开。
样例输入
10
back -9
left 3
left 8
back 15
right 10
right -7
right -3
left 11
right 17
left 3
样例输出
9 -7
分析:拿到这样一个问题,首先想到的事不难,应该很简单,坐标有四个方向,直接写出关于四个方向的方法定义就行了,虽然确实是如此,但是我们不得不考虑一个问题,机器人是有正面的,每一次的转向都是相对于他自己,而不是坐标轴。而我们需要的答案却是坐标轴值。所以我们光简单的规定坐标的方向是不行的,我们还要定义机器人的方向(机器人面对的方向),并在两个方向上建立一定的联系。
就比如题目所说,机器人首先是面对x轴正方向,机器人可以向任何一个方向移动,但是移动之后不仅仅是坐标轴值改变了,对于机器人本身而言,相对于机器人的方向也变了。比如机器人第一步要向x轴负方向走 -8米,我们知道,朝负方向走 -8米,其实相当于正方向走了 8米,但是此时的机器人朝向已经改变,从面相x正半轴变为面向x负半轴。而对于下一次的移动,机器人还是针对于自身的前后左右进行移动,并且这种变化每一次移动都会改变。
经过上述分析(如果有疑惑可以自己画个图,很简单就能理解),我们知道,需要定义一个值来表示机器人此时的朝向(机器人相对于坐标轴)。在接下来的代码中,用headTo表示,其值是 1,2,3,4.分别代表朝x+,y-,x-,y+ 方向。对于代码中的其他方法基本上就能见名知意了,此时还有一个需要注意的细节:
在机器人每一次移动后,我们需要更新机器人的朝向信息,也就是headTo的值,不然不能得到正确结果。整体代码如下:
import java.util.Scanner;
public class RobotWalking
{
private int x;
private int y;
private int headTo;
public RobotWalking()
{
this.x=0;
this.y=0;
//default head to x+; 2 stand for y-;3 stand for x-;4 stand for y+;
this.headTo=1;
}
public void direction(int dir)
{
this.headTo=dir;
}
/*The fallowing 4 methods:4 kinds of actions of the robot
Every time you move the robot,you had to change the direction info of the robot
*/
public void UP(int steps)
{
switch(this.headTo)
{
case 1:this.x+=steps;this.headTo=1;break;
case 2:this.y-=steps;this.headTo=2;break;
case 3:this.x-=steps;this.headTo=3;break;
case 4:this.y+=steps;this.headTo=4;break;
}
}
public void DOWN(int steps)
{
switch(this.headTo)
{
case 1:this.x-=steps;this.headTo=3;break;
case 2:this.y+=steps;this.headTo=4;break;
case 3:this.x+=steps;this.headTo=1;break;
case 4:this.y-=steps;this.headTo=2;break;
}
}
public void RIGHT(int steps)
{
switch(this.headTo)
{
case 1:this.y-=steps;this.headTo=2;break;
case 2:this.x-=steps;this.headTo=3;break;
case 3:this.y+=steps;this.headTo=4;break;
case 4:this.x+=steps;this.headTo=1;break;
}
}
public void LEFT(int steps)
{
switch(this.headTo)
{
case 1:this.y+=steps;this.headTo=4;break;
case 2:this.x+=steps;this.headTo=1;break;
case 3:this.y-=steps;this.headTo=2;break;
case 4:this.x-=steps;this.headTo=3;break;
}
}
//Method to display the robot locatipn!
public void GetLocation()
{
System.out.println(this.x+" "+this.y);
}
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int numbers=sc.nextInt();
//Save the code which can control the moving directions of the robot
String[] method=new String[numbers];
//Save the steps number of every move
int steps[]=new int[numbers];
for(int i=0;i<numbers;i++)
{
method[i]=sc.next();
steps[i]=sc.nextInt();
}
RobotWalking test=new RobotWalking();
//Start to move the robot and calculate the final location!
for(int i=0;i<numbers;i++)
{
switch(method[i])
{
case "forward":test.UP(steps[i]);break;
case "back":test.DOWN(steps[i]);break;
case "left":test.LEFT(steps[i]);break;
case "right":test.RIGHT(steps[i]);break;
}
}
test.GetLocation();
}
}
运行结果如图:
submit and test!:
PERFECT & AMUSIVE!!!