火星漫游车问题

一队机器人漫游车将被美国宇航局降落在火星高原上。漫游车将在这个奇怪的长方形高原上巡游,以便他们的机载摄像头可以获得周围地形的完整视图,并将其发送回地球。漫游者的坐标和位置由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

package com.lionel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;


/**
 * 
 * @author lionel
 * 
 * 一队机器人漫游车将被美国宇航局降落在火星高原上。漫游车将在这个奇怪的长方形高原上巡游,
 * 以便他们的机载摄像头可以获得周围地形的完整视图,并将其发送回地球。
 * 漫游者的坐标和位置由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
 * 
 */
public class Demo1 {
     /*
     * 坐标指令正则
     */
    static final String coordinatesRegex="^\\d+\\s\\d+$";
    /*
     * 位置指令正则
     */
    static final String positionRegex="^\\d+\\s\\d+\\s[E,S,W,N]$";
    /*
     * 操作指令正则
     */
    static final String operationRegex="^[L,R,M]+$";
    /*
     * 多个车的索引
     */
    static int index=1;

    public static void main(String[] args) {
        //右上角坐标
        String maxCoordinates="";
        //初始位置
        String oldPosition="";
        //操作指令
        String operater="";
        //多个车辆集合
        List<Map<String,String>> carList=new ArrayList<Map<String,String>>();

        Scanner scan=new Scanner(System.in);

        System.out.println("请输入右上角坐标:");
        String maxCoordinatesInput=scan.nextLine();
        maxCoordinates=checkMaxCoordinatesInput(maxCoordinatesInput,scan);      

        //录入车辆信息,输入quit退出,当前未输入完整信息的车不生效
        while(true) {
            System.out.println("请输入第"+index+"个车的初始位置(输入quit结束输入(当前车的指令无效)):");
            String oldPositionInput=scan.nextLine();
            oldPositionInput=oldPositionInput.toUpperCase();
            if("QUIT".equals(oldPositionInput)) {
                break;
            }
            oldPosition=checkOldPositionInput(oldPositionInput,scan);       
            if("QUIT".equals(oldPosition)) {
                break;
            }
            System.out.println("请输入第"+index+"个车的操作指令(输入quit结束输入(当前车的指令无效)):");
            String operaterInput=scan.nextLine();
            operaterInput=operaterInput.toUpperCase();
            if("QUIT".equals(operaterInput)) {
                break;
            }
            operater=checkOperaterInput(operaterInput,scan);
            if("QUIT".equals(operater)) {
                break;
            }
            Map<String,String> car=new HashMap<String,String>();
            car.put("oldPosition", oldPosition);
            car.put("operater", operater);
            carList.add(car);
            index++;
        }

        //循环输入先存车辆的最后位置
        for(int i=0;i<carList.size();i++) {
            String newPosition=getNewPosition(maxCoordinates,carList.get(i).get("oldPosition"),carList.get(i).get("operater"));
            System.out.println();
            System.out.println("第"+(i+1)+"个车的最后位置为:"+newPosition);
        }
    }

    /**
     * 右上角坐标输入信息的合法性检查
     * 
     * @param maxCoordinatesInput 输入的右上角坐标
     * @param scan
     * @return 返回合法的值
     */
    public static String checkMaxCoordinatesInput(String maxCoordinatesInput,Scanner scan) {
        while(!maxCoordinatesInput.matches(coordinatesRegex)) {
            System.out.println("输入内容不合法,请重新输入右上角坐标:");
            maxCoordinatesInput=scan.nextLine();
        }
        return maxCoordinatesInput;
    }

    /**
     * 初始位置输入信息的合法性检查
     * @param oldPositionInput 输入的初始位置
     * @param scan
     * @return 返回合法的值
     */
    public static String checkOldPositionInput(String oldPositionInput,Scanner scan) {
        while(!oldPositionInput.matches(positionRegex)) {
            System.out.println("输入内容不合法,请重新输入第"+index+"个车的初始位置(输入quit结束输入(当前车的指令无效)):");
            oldPositionInput=scan.nextLine();
            oldPositionInput=oldPositionInput.toUpperCase();
            if("QUIT".equals(oldPositionInput)) {
                break;
            }
        }
        return oldPositionInput;
    }

    /**
     * 操作指令的合法性检查
     * @param operaterInput 输入的操作指令
     * @param scan
     * @return 返回合法的值
     */
    public static String checkOperaterInput(String operaterInput,Scanner scan) {
        while(!operaterInput.matches(operationRegex)) {
            System.out.println("输入内容不合法,请重新输入第"+index+"个车的操作指令(输入quit结束输入(当前车的指令无效)):");
            operaterInput=scan.nextLine();
            operaterInput=operaterInput.toUpperCase();
            if("QUIT".equals(operaterInput)) {
                break;
            }
        }
        return operaterInput;
    }

    /**
     * 根据指令获得新的位置
     * 
     * @param maxCoordinates 右上角坐标
     * @param oldPosition 初始位置
     * @param operater 操作指令
     * @return
     */
    public static String getNewPosition(String maxCoordinates,String oldPosition,String operater) {
        //解析右上角坐标(可移动的最大值)
        String[] mc=maxCoordinates.split(" ");
        //解析初始坐标与方向
        String[] op=oldPosition.split(" ");
        //创建初始位置坐标map对象
        Map<String,Integer> opm=new HashMap<String,Integer>();
        opm.put("x", Integer.parseInt(op[0]));
        opm.put("y", Integer.parseInt(op[1]));

        //初始位置方向
        String direction=op[2];

        //根据操作指令获得最后的方向与坐标
        for(int i=0;i<operater.length();i++) {
            if("L".equals(operater.charAt(i)+"")){
                direction=getNewDirection(direction,"L");
            }
            if("R".equals(operater.charAt(i)+"")){
                direction=getNewDirection(direction,"R");
            }
            if("M".equals(operater.charAt(i)+"")){
                opm=getNewCoordinates(mc,direction,opm);
            }
        }

        String newPoisition=opm.get("x")+" "+opm.get("y")+" "+direction;
        return newPoisition;
    }



    /**
     * 移动的方法,获得移动后的坐标(无法超过最大移动范围)
     * 指令中存在"M"的时候执行
     * 
     * @param mc 右上角坐标值(最大可以移动到的位置,最小为(0,0))
     * @param direction 当前位置方向
     * @param oldM 当前位置坐标
     * @return 返回移动后的坐标
     */
    public static Map<String,Integer> getNewCoordinates(String[] mc,String direction,Map<String,Integer> oldM) {
        //解析右上角坐标值(最大值)
        int maxX=Integer.parseInt(mc[0]);
        int maxY=Integer.parseInt(mc[1]);

        //根据不同方向对坐标值进行操作
        if("E".equals(direction)) {
            Map<String,Integer> m=new HashMap<String,Integer>();
            if((oldM.get("x")+1)<=maxX) {
                m.put("x", oldM.get("x")+1);
            }else {
                m.put("x", maxX);
            }
            m.put("y", oldM.get("y"));
            return m;
        }
        if("S".equals(direction)) {
            Map<String,Integer> m=new HashMap<String,Integer>();
            m.put("x", oldM.get("x"));
            if((oldM.get("y")-1)>=0) {
                m.put("y", oldM.get("y")-1);
            }else{
                m.put("y", 0);
            }
            return m;
        }
        if("W".equals(direction)) {
            Map<String,Integer> m=new HashMap<String,Integer>();
            if((oldM.get("x")-1)>=0) {
                m.put("x", oldM.get("x")-1);
            }else {
                m.put("x", 0);
            }
            m.put("y", oldM.get("y"));
            return m;
        }
        if("N".equals(direction)) {
            Map<String,Integer> m=new HashMap<String,Integer>();
            m.put("x", oldM.get("x"));
            if((oldM.get("y")+1)<=maxY) {
                m.put("y", oldM.get("y")+1);
            }else{
                m.put("y", maxY);
            }
            return m;
        }
        return null;
    }

    /**
     * 根据原方向和转动的操作获得新的方向
     * 指令中存在"L"和"R"的时候执行
     * 
     * @param oldDirection 当前位置方向
     * @param operation 旋转操作"L"或者"R"
     * @return 返回旋转后的方向
     */
    public static String getNewDirection(String oldDirection,String operation) {
        //方向顺时针顺序
        String d="ESWN";
        int index = 0;

        //根据初始位置查看在字符串中的位置
        if(oldDirection!=null&&oldDirection!="") {
            index=d.indexOf(oldDirection);
        }

        //根据旋转方向不同操作在字符串中的位置
        if(index!=-1) {
            if("L".equals(operation)) {
                index-=1;
            }
            if("R".equals(operation)) {
                index+=1;
            }
        }

        //用算法转换-1与4这种超界限的值
        return d.charAt((index+4)%4)+"";
    }
}

《火星漫游车问题》有2个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注