搜索与图论 - 走迷宫

1、题目描述

给定一个n*m的二维整数数组,用来表示一个迷宫,数组中只包含0或1,其中0表示可以走的路,1表示不可通过的墙壁。

最初,有一个人位于左上角(1, 1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。

请问,该人从左上角移动至右下角(n, m)处,至少需要移动多少次。

数据保证(1, 1)处和(n, m)处的数字为0,且一定至少存在一条通路。

输入格式

第一行包含两个整数n和m。

接下来n行,每行包含m个整数(0或1),表示完整的二维数组迷宫。

输出格式

输出一个整数,表示从左上角移动至右下角的最少移动次数。

数据范围

1≤n,m≤1001≤n,m≤100

输入样例:

5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出样例:

8

 

2、分析

(1)使用宽度优先搜索,每一次走过的都是距离出发点最近的点。

 (2)宽搜的基本代码逻辑

 

3、代码

package cn.acwing.搜索与图论;

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

class Pair{
	int first;
	int second;
	public Pair(int a,int b){
		this.first = a;
		this.second = b;
	}
	
}

public class 走迷宫 {
	static int[][] g;
	static int[][] d; //距离
	static Queue<Pair> q = new LinkedList<>();
	static int[] dx = {0, 1, 0, -1};
	static int[] dy = {-1, 0, 1, 0};
	static int n, m;
	
	static int bfs(int x, int y){
		d[0][0] = 0;
		Pair pair = new Pair(0, 0);
		q.add(pair);
		while(!q.isEmpty()){ //队列非空
			//取出队头元素
			Pair head = q.poll();
			//扩展队头元素
			for(int i = 0;i < 4;i ++){
				int row = head.first;
				int col = head.second;
				row += dx[i];
				col += dy[i];
				if(row >= 0 && row < n && col >= 0 && col < m && g[row][col] == 0 && d[row][col] == -1){
					Pair p = new Pair(row, col);
					q.add(p);
					d[row][col] = d[head.first][head.second] + 1; //走过的距离加1
				}
			}
		}
		return d[n-1][m-1];
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(new InputStreamReader(System.in));
		n = in.nextInt();
		m = in.nextInt();
		
		g = new int[n][m];
		d = new int[n][m];
		
		for(int i = 0;i < n;i ++){
			for(int j = 0;j < m;j ++){
				g[i][j] = in.nextInt();
				d[i][j] = -1; //表示都没有走过
			}
		}
		System.out.println(bfs(0, 0));
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值