混境之地2 java

自己写的 通过样例19/20

思路

用bfs对地图进行搜索,对于每一个点,对其四个方向进行搜索,用#标记是已经搜索过的,使用魔法我这里理解的就是跳两步,看是否到达终点,有局限性哈

改进的

从起点开始搜索,标记为1
从终点开始搜索,标记为2
使用魔法跳两步,看到达的地方是否与这一趟的数字不同,若不同则找到一条路,这句话的意思是说,我从起点搜一次,从终点搜一次,在从终点搜索的狮虎我每次向前考虑两步,如果前进两步后出现了1,那么表明打破这个障碍物后能找到一条路,待会试试

改进的

这个能ac

  1. 从起点搜一遍
  2. 若能找到出口则退出,反之从终点搜一遍
  3. 遍历地图,找障碍物,对障碍物的四个方向进行遍历,如果障碍物的四个方向中其中有两个方向是1或2那么u就是3,这也就是为什么check函数最后返回的是u==3的原因
  4. 这都找不到出口,那是真没有了

代码

import java.util.*;

public class Main{
    static int row,col;
    static int[] start;
    static int[] end;
    static char[][] map;
    static int[][] direct = {
            {0,1},
            {0,-1},
            {1,0},
            {-1,0},

    };
    static int[][] magic = {
            {0,2},
            {0,-2},
            {2,0},
            {-2,0},
    };
    static boolean flag = false; //使用魔法标志
    public static boolean checkNorm(int curX,int curY){
        if(curX>row || curX<=0
                || curY>col || curY<=0
                || map[curX][curY]=='#'
        )
            return false;
        return true;
    }
    public static boolean checkMagic(int curX,int curY){
        boolean norm = checkNorm(curX,curY);
        if(norm && curX==end[0] && curY == end[1])
            return true;
        return false;
    }
    public static boolean bfs(){

        Queue<Integer[]> queue =new LinkedList<>();
        queue.add(new Integer[]{start[0],start[1]});
        map[start[0]][start[1]]='#';// 标记访问过了
        while (!queue.isEmpty()){
            Integer[] temp = queue.poll();
            if(temp[0] == end[0] && temp[1] ==end[1])
                return true;
            for(int i=0;i<4;i++){
                int curX = temp[0] + direct[i][0];
                int curY = temp[1] + direct[i][1];
                //尝试使用一次魔法
                int magicX = temp[0] + magic[i][0];
                int magicY = temp[1] + magic[i][1];
                if(checkMagic(magicX,magicY)){
                    flag = true;
                    return true;
                }
                // 正常情况下的curX curY边界性检查
                if(!checkNorm(curX,curY))
                    continue;

                queue.add(new Integer[]{curX,curY});
                map[curX][curY] = '#';// 标记访问过了
            }
        }
        return false;
    }
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        row = s.nextInt();
        col = s.nextInt();
        map = new char[row+1][col+1];
        start = new int[2];
        end = new int[2];
        start[0] = s.nextInt();
        start[1] = s.nextInt();
        end[0] = s.nextInt();
        end[1] = s.nextInt();
        for(int i=1;i<=row;i++){
            map[i] = (" "+ s.next()).toCharArray();
        }
        boolean res = bfs();
        System.out.println(res?"Yes":"No");
        s.close();
    }
}

改进的

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;


public class Main {
    static boolean res;
    static int row,col;
    static char[][] map;
    static int[][] used;
    static int[][] direct  = {{0,1},{0,-1},{1,0},{-1,0}};
    static int[] start = new int[2],end = new int[2];
    public static void bfs(int x,int y,int c){
        Queue<Integer[]> queue = new LinkedList<>();
        queue.add(new Integer[]{x,y});
        used[x][y]=c;
        while (!queue.isEmpty()){
            Integer[] poll = queue.poll();

            for(int i=0;i<4;i++){
                int curX = poll[0] + direct[i][0];
                int curY = poll[1] + direct[i][1];
                if(c==1&&curX == end[0] && curY == end[1])
                {
                    res=true;
                    return;
                }else if(c==2 && curX == start[0] && curY == start[1]){
                    res=true;
                    return;
                }
                if(curY > col || curY <=0 ||
                   curX > row || curX <=0 ||
                   map[curX][curY]=='#' || used[curX][curY]!=0)
                    continue;
                used[curX][curY] = c;
                queue.add(new Integer[]{curX,curY});
            }
        }
    }
    public static boolean check(int x,int y){
        int u = 0;
        for(int i=0;i<4;i++){
            int curX = x + direct[i][0];
            int curY = y + direct[i][1];
            if(curY > col || curY <=0 ||
                    curX > row || curX <=0)
                continue;
            u|=used[curX][curY];
        }
        return u==3;
    }


    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
        row = s.nextInt();
        col = s.nextInt();
        map = new char[row+1][col+1];
        used = new int[row+1][col+1];
        start[0] = s.nextInt();
        start[1] = s.nextInt();
        end[0] = s.nextInt();
        end[1] = s.nextInt();
        for(int i=1;i<=row;i++){
            map[i] = (" "+s.next()).toCharArray();
        }
        bfs(start[0],start[1],1 );
        if(res){
            System.out.println("Yes");
        }else{
            bfs(end[0],end[1],2 );
            for(int i=1;i<=row;i++){
                for(int j=1;j<=col;j++){
                    if(map[i][j]=='#' && check(i,j))
                    {
                        System.out.println("Yes");
                        return;
                    }
                }
            }
            System.out.println("No");
        }

        s.close();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值