绕开陨石救人(星环笔试2题)

绕开陨石救人(星环笔试2题)

题目描述:

对于一个8 * 8的矩阵:

  • M(Maria)要绕开S(Stones)去解救A
  • M先移动,石头再移动,两者轮流移动
  • M每次有9个方向可以移动(可以原地不动)
  • 所有石头只能向下移动

M是否在不碰到S的情况下把A解救出来

用例1:
输入:
.......A
........
........
........ 
........
........
M.......

输出:
WIN
用例2:
输入
.......A
........
........
........
........
........
SS......
M.......

输出
LOSE
解题思路
  • 深搜 + 剪枝M碰撞到S则回溯;M上面没S则直接返回True);
  • 石头S最多7轮就消失在这个棋盘中,此时M就能解救到A了;
参考代码:
// 本题为考试多行输入输出规范示例,无需提交,不计分。
package java_algo;
// 本题为考试多行输入输出规范示例,无需提交,不计分。
import java.util.Scanner;
import java.util.ArrayList;

class Coord{
    public int x = 0;
    public int y = 0;
    public Coord(int x, int y){
        this.x = x;
        this.y = y;
    }
}

public class Main {
    
    public int[][] moves = new int[][]{
        {-1,-1},{-1,0},{-1,1}, //向上移动
        {0,-1},{0,0},{0,1},    //左右移动
        {1,-1},{1,0},{1,1}  //向下移动
    }; //9个方向  [9][2]
    
    public boolean border_judge(Coord cord){
        int x = cord.x,y = cord.y;
        if(x >= 0 && y >= 0 && x < 8 && y < 8){
            return true;
        }
        return false;
    }
    
    //碰撞检测
    public boolean isCrash(Coord maria, ArrayList<Coord> stones){
        for(Coord stone : stones){
            if(stone.x == maria.x && stone.y == maria.y){
                return true;
            }
        }
        return false;
    }

    //maria上面有没有石头
    public boolean no_StonesUp(Coord maria, ArrayList<Coord> stones){
        for(Coord stone : stones){
            if(stone.x < maria.x){
                return false;
            }
        }
        return true;
    }
    
    public boolean solve(ArrayList<Coord> stones, Coord maria, Coord Anna){
        
        if(maria.x == Anna.x && maria.y == Anna.y){
            return true;
        }
        
        //maria先移动(9个方向移动)
        boolean flag = false;
        for(int i = 0; i < 9; i++){
            maria.x += moves[i][0];
            maria.y += moves[i][1];
            if(border_judge(maria) && !isCrash(maria,stones)){  //边界检测和碰撞检测

                System.out.println(maria.x + "," + maria.y);
                //stones再整体向南移动
                for(Coord stone : stones){
                    stone.x++;
                }
                
                //碰撞检测,如果没碰撞则继续深搜,
                if(!isCrash(maria,stones)){
                    //如果上面没有石头,则直接返回True
                    if(no_StonesUp(maria,stones) == false){
                        flag = solve(stones,maria,Anna);
                    }else{
                        return true;
                    }
                }
                
                if(flag){
                    //重置
                    maria.x -= moves[i][0];
                    maria.y -= moves[i][1];
                    return true;
                }
            }
            maria.x -= moves[i][0];
            maria.y -= moves[i][1];
        }
        return false;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Main obj = new Main();
        
        // int graph[][] = new int[8][8];
        ArrayList<Coord> stones = new ArrayList<Coord>();
        
        //将图转换成二维数组arr[8][8]
        int row = 0;
        Coord Anna = null;
        Coord maria = null; //Maria坐标
        while(sc.hasNextLine()){
            String str = sc.nextLine();
            for(int col = 0; col < str.length(); ++col){
                char c = str.charAt(col);
                if(c == '.'){ //空格为0
                    // graph[row][col] = 0;
                }else if(c == 'S'){  //石头为1
                    // graph[row][col] = 1;
                    stones.add(new Coord(row,col));
                }else if(c == 'A'){  //A为2
                    // graph[row][col] = 2;
                    Anna = new Coord(row,col);
                }else if(c == 'M'){  //B为3
                    // graph[row][col] = 3;
                    maria = new Coord(row,col);
                }
            }
            row++;
            if(row >= 8){
                break;
            }
        }
//         for(Coord cord : stones){
//             System.out.println(cord.x + "," + cord.y);
//         }
        boolean res = obj.solve(stones,maria,Anna);
        
        String str = res == true ? "WIN" : "LOSE";
        System.out.println(str);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值