为了不掉线,最近要补补.
- 其一:面试题,
- 其二:基础知识.
- 其三:洗干净眼睛,好好看
昨晚在浙大门口摔了一跤,直到今天上午,腿脚一直不变,膝盖肿成了西瓜,苦逼就是在下了,摔倒爬起就跑,可真是丢脸了.年纪大了,容易碎碎念,请看下面题目.
题目:
一队机器人漫游车将被美国宇航局降落在火星高原上。漫游车将在这个奇怪的长方形高原上巡游,以便他们的机载摄像头可以获得周围地形的完整视图,并将其发送回地球。 漫游者的坐标和位置由x和y坐标的组合以及代表四个方向(E, S, W, N)的字母表示。高原划分为网格以简化导航。比如位置0,0,N,表示漫游车位于左下角并面向北。 为了控制漫游车,美国宇航局发送一串简单的字母。指令字母是'L','R'和'M'。 'L'和'R'使漫游车分别向左或向右旋转90度,而不会从当前地点移动。 'M'表示前进一个网格点,并保持相同的方向。
假设从(x,y)直接向北移动,就到了(x,y + 1)。
INPUT:
第一行输入是平台的右上角坐标,左下角坐标被假定为0,0。
其余的输入是有关已部署的漫游车的信息。每个漫游车都有两行输入。第一行给出了漫游车的位置,第二行是告诉漫游车如何探索高原的一系列指令。位置由两个整数和一个由空格分隔的字母组成,对应于x和y坐标以及漫游车当前的方向。
每个漫游车将按顺序完成,这意味着第二个漫游车在第一个漫游车完成移动之前不会开始移动。
OUTPUT:
每个漫游车的输出应该是其最终的坐标和位置。
输入输出例子
输入:
5 5
1 2 N
LMLMLMLMM
3 3 E
MMRMMRMRRM
预期产出:
1 3 N
5 1 E
我的思路:
其中无非是根据小车的位置和方向,来执行小车的行为轨迹,其中方向确定这个是问题,还有就是更具方向在确定行动方向这个也就好办了,我觉的最主要的就是得到小车的当前的方向,然后在进行计算.
首先先封装小车:
@Data
@AllArgsConstructor
class Point {
private int x;
private int y;
}
@Data
class Car{
private Point posintion;
private int direction;
public Car(Point posintion, int direction) throws Exception {
if(!Objects.isNull(posintion) && !VisitorCar.isCrossing(posintion)){
throw new Exception("小车位置初始化失败!");
}
this.posintion = posintion;
this.direction = direction;
}
}
这里用到一个插件lombok,可以了解下,这个东东超级好用.
既然这样,我想先把方向封装起来,如下:
interface BaseDirection{
int getKey();
String getValue();
}
enum Direction implements BaseDirection{
E(360,"E"),N(90,"N"),W(180,"W"),S(270,"S");
private int key;
private String value;
Direction(int key, String value) {
this.key = key;
this.value = value;
}
@Override
public int getKey() {
return key;
}
@Override
public String getValue() {
return value;
}
}
根据角度计算方向值.先将输入的方向值转换成角度在计算,这就好计算了,看是向左向右,无非是加上360后在取余从而获取其角度计算其方向,在根据其方向,决定下次移动的时候是的坐标位置操作.
比如:
(1,,2,90) == (1,2) N
左转:
L 操作后: (1,2,180)
M操作后: (0,2,180)
L 操作后: (0,2,270)
M 操作后: (0,1,180)
右转:
R 操作后: (1,2,0)
M操作后: (2,2,0)
R 操作后: (2,2,-90)
M 操作后: (2,1,-90)
这样操作起来就很容易了.代码如下:
/**
* 根据角度获取方向参数
*
* @param key
* @return
*/
private static String getPosition(int key){
if(key < 0){ key = 360+key; }
Direction[] values = Direction.values();
key = (key == 0 || key == 360? 360:key%360);
for (Direction d : values){
int key1 = Direction.valueOf(d.getValue()).getKey();
if(key1 == key) {
return d.getValue();
}
}
return null;
}
接下来就是小车的具体操作了:
/**
* 操作小车
*
* @param car
* @param operate
* @return
*/
private static Car operateCar(Car car, String operate) throws Exception {
//获取小车方向
int direction = car.getDirection();
//获取小车位置
Point positionXY = car.getPosintion();
int endDirection = 0;
char[] chars = operate.toCharArray();
for (char aChar : chars) {
switch (aChar){
case 'L':
direction += 90;
break;
case 'R':
direction -= 90;
break;
case 'M':
int x = positionXY.getX();
int y = positionXY.getY();
String position = getPosition(direction);
switch (position){
case "E":
positionXY.setX(x+1);
break;
case "W":
positionXY.setX(x-1);
break;
case "N":
positionXY.setY(y+1);
break;
case "S":
positionXY.setY(y-1);
break;
default:
System.out.println("移动小车失败!");
break;
}
break;
default:
break;
}
endDirection = direction;
}
return new Car(positionXY,endDirection);
}
好了,主要逻辑代码就写完了,是不是很简单呢!放出完整的程序:
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Objects;
import java.util.Scanner;
/**
* @author: zhangyi
* @date: 2019/4/17 22:12
* @description:
*/
public class VisitorCar {
public static final String SPIL = " ";
public static final Point minPoint = new Point(0,0);
public static final Point maxPoint = new Point(0,0);
/**
*
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Car car = null;
Scanner scanner = new Scanner(System.in);
//获取输入
System.out.println("输入坐标网格最大坐标:");
String s = scanner.nextLine();
Integer[] integers = paseInts(s.split(SPIL));
if(!Objects.isNull(integers) && integers.length == 2){
maxPoint.setX(integers[0]);
maxPoint.setY(integers[1]);
}
System.out.println("输入需要小车个数:");
Integer carCount = Integer.parseInt(scanner.nextLine().trim());
for (Integer integer = 0; integer < carCount; integer++) {
Car carEnd = moveCar(scanner, car,integer);
int direction = carEnd.getDirection();
Point posintion = carEnd.getPosintion();
int x = posintion.getX();
int y = posintion.getY();
String position = getPosition(direction);
System.out.println(x+" "+y+" "+position);
}
}
/**
* 车移动操作
*
* @return
*/
private static Car moveCar(Scanner scanner,Car car,int index) throws Exception {
System.out.println("输入第"+(index+1)+"初始化小车位置+方向:");
String carPoint = scanner.nextLine();
if(!Objects.isNull(carPoint)){
Integer[] pos = paseInts(carPoint.split(SPIL));
car = new Car(new Point(pos[0],pos[1]),pos[2]);
}
System.out.println("输入第"+(index+1)+"小车操作指令:");
String operate = scanner.nextLine();
Car carEnd = operateCar(car,operate);
return carEnd;
}
/**
* 根据角度获取方向参数
*
* @param key
* @return
*/
private static String getPosition(int key){
if(key < 0){ key = 360+key; }
Direction[] values = Direction.values();
key = (key == 0 || key == 360? 360:key%360);
for (Direction d : values){
int key1 = Direction.valueOf(d.getValue()).getKey();
if(key1 == key) {
return d.getValue();
}
}
return null;
}
/**
* 操作小车
*
* @param car
* @param operate
* @return
*/
private static Car operateCar(Car car, String operate) throws Exception {
//获取小车方向
int direction = car.getDirection();
//获取小车位置
Point positionXY = car.getPosintion();
int endDirection = 0;
char[] chars = operate.toCharArray();
for (char aChar : chars) {
switch (aChar){
case 'L':
direction += 90;
break;
case 'R':
direction -= 90;
break;
case 'M':
int x = positionXY.getX();
int y = positionXY.getY();
String position = getPosition(direction);
switch (position){
case "E":
positionXY.setX(x+1);
break;
case "W":
positionXY.setX(x-1);
break;
case "N":
positionXY.setY(y+1);
break;
case "S":
positionXY.setY(y-1);
break;
default:
System.out.println("移动小车失败!");
break;
}
break;
default:
break;
}
endDirection = direction;
}
return new Car(positionXY,endDirection);
}
/**
* 字符串数组转化
*
* @param strs
* @return
*/
private static Integer[] paseInts(String[] strs){
Integer[] integers = new Integer[strs.length];
for (int i = 0; i < strs.length; i++) {
switch (strs[i]){
case "E":
case "W":
case "S":
case "N":
integers[i] = Direction.valueOf(strs[i]).getKey();
break;
default:
integers[i] = Integer.parseInt(strs[i]);
break;
}
}
return integers;
}
/**
* 越界处理
*
* @param point
* @return
*/
public static boolean isCrossing(Point point){
return point.getX() <= maxPoint.getX() && point.getY() <= maxPoint.getY();
}
}
@Data
@AllArgsConstructor
class Point {
private int x;
private int y;
}
@Data
class Car{
private Point posintion;
private int direction;
public Car(Point posintion, int direction) throws Exception {
if(!Objects.isNull(posintion) && !VisitorCar.isCrossing(posintion)){
throw new Exception("小车位置初始化失败!");
}
this.posintion = posintion;
this.direction = direction;
}
}
interface BaseDirection{
int getKey();
String getValue();
}
enum Direction implements BaseDirection{
E(360,"E"),N(90,"N"),W(180,"W"),S(270,"S");
private int key;
private String value;
Direction(int key, String value) {
this.key = key;
this.value = value;
}
@Override
public int getKey() {
return key;
}
@Override
public String getValue() {
return value;
}
}
结果:
还需要优化的地方:
输入参数校验可以在做些比较.
我这里并不是安装题目要求的输入全部指定后在进行一个一个操作,为啥?可以把小车操作封装起来,在一个集合中按照次序操作,腿痛死了......暂时写到这咯.
小车结尾,-__-,Thank you for seeing here, I hope you will come again next time.