首页 > 试题广场 >

迷宫寻路

[编程题]迷宫寻路
  • 热度指数:4662 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}旺仔哥哥被困在一个 n\times m矩形迷宫里。每个格子要么是空地 (用符号 `.` 表示),要么是墙 (用符号 `#` 表示)。旺仔哥哥只能从一个空地移动到其上下左右相邻的空地。
\hspace{15pt}已知旺仔哥哥的起点为左上角 (1,1),终点为右下角 (n,m)。请判断他是否能够到达终点。

输入描述:
\hspace{15pt}第一行输入两个正整数 n,m\ (1\leqq n,m\leqq 100)
\hspace{15pt}接下来的 n 行每行输入一个长为 m 的仅包含字符 `.` 与 `#` 的字符串,描述整个迷宫。
\hspace{15pt}保证起点 (1,1) 和终点 (n,m) 均为空地。


输出描述:
\hspace{15pt}若旺仔哥哥可以走到终点,则输出单词 \text{Yes};否则输出 \text{No}
示例1

输入

3 5
.##.#
.#...
...#.

输出

Yes

说明

路线如下:(1,1)\to (2,1) \to (3,1) \to (3,2)\to (3,3) \to (2, 3) \to (2, 4) \to (2, 5) \to (3, 5)
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int a = in.nextInt();
            int b = in.nextInt();
            char[][] map = new char[a+2][b+2];//地图外围一圈边界,避免数组越界
            for(int i = 1; i < a+1; i++){
                String str = in.next();
                for(int j = 1; j < b+1; j++){
                    map[i][j] = str.charAt(j-1);
                }
            }
            System.out.println(method(1,1,map,a,b) ? "Yes" : "No");
        }
    }
    public static boolean method(int ia,int ib,char[][] map,int a,int b){//a,b代表终点
        map[ia][ib] = '#';//标记走过的点
        if(ia == a && ib == b){return true;}//到达终点
        if(map[ia][ib-1] == '.'){if (method(ia,ib-1,map,a,b)) return true;}//向上走
        if(map[ia][ib+1] == '.'){if (method(ia,ib+1,map,a,b)) return true;}//向下走
        if(map[ia-1][ib] == '.'){if (method(ia-1,ib,map,a,b)) return true;}//向左走
        if(map[ia+1][ib] == '.'){if (method(ia+1,ib,map,a,b)) return true;}//向右走
        return false;
    }
}

发表于 2025-11-15 00:10:54 回复(0)
n , m = map(int,input().split())
arr = []
for i in range(n):
    arr.append(list(input()))
graph = {}
for i in range(n):
    for j in range(m):
        if arr[i][j] == ".":
            graph[(i,j)] = []
            if i - 1 >= 0 and arr[i-1][j]==".":
                graph[(i,j)].append((i-1,j))
            if j - 1 >= 0 and arr[i][j-1]==".":
                graph[(i,j)].append((i,j-1))
            if j + 1 <= m - 1 and arr[i][j+1]==".":
                graph[(i,j)].append((i,j+1))
            if i + 1 <= n - 1 and arr[i+1][j]==".":
                graph[(i,j)].append((i+1,j))
# print(graph)
def can_reach(graph, start, target):
    stack = [start]
    visited = set()
    while stack:
        current = stack.pop()
        if current == target:
            return "Yes"
        if current in visited:
            continue
        visited.add(current)
        for neighbor in graph[current]:
            if neighbor not in visited:
                stack.append(neighbor)
    return "No"
print(can_reach(graph,(0,0),(n-1,m-1)))

发表于 2025-08-28 16:08:49 回复(0)
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {

    private static boolean[][] visited;

    private static int[][] direction = new int[][] {
        {-1, 0}, {1, 0}, {0, -1}, {0, 1}
    };

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String[] line = in.nextLine().split(" ");
            int n = Integer.parseInt(line[0]);
            int m = Integer.parseInt(line[1]);
            visited = new boolean[n][m];
            char[][] matrix = new char[n][m];
            for (int i = 0; i < n; i++) {
                matrix[i] = in.nextLine().toCharArray();
            }

            Queue<Point> queue = new LinkedList<>();
            queue.add(new Point(0, 0));
            visited[0][0] = true;
            boolean isArrive = false;

            Point cur = null;
            while (!queue.isEmpty()) {
                cur = queue.poll();

                // 到达终点,直接返回
                if (cur.x == n - 1 && cur.y == m - 1) {
                    System.out.println("Yes");
                    isArrive = true;
                    break;
                }

                // 若符合条件,上下左右遍历
                for (int i = 0; i < direction.length; i++) {
                    int dx = cur.x + direction[i][0];
                    int dy = cur.y + direction[i][1];

                    if (dx >= 0 && dx < n && dy >= 0 && dy < m && !visited[dx][dy] && matrix[dx][dy] == '.') {
                        queue.add(new Point(dx, dy));
                        visited[dx][dy] = true;
                    }
                }
            }

            // 到达出口的标志位未改变,说明没有出口
            if (!isArrive) {
                System.out.println("No");
            }
        }
    }
}

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

发表于 2025-12-08 14:53:19 回复(0)
这里dfs和bfs均可以解决,在这里我使用bfs,后面还提供了dfs方法,将bfs中的queue队列换成了stack显示栈
#include <iostream>
#include <string>
#include <vector>
#include <queue>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;

    vector<string> maze(n);
    for (int i = 0; i < n; i++) {
        cin >> maze[i];
    }

    // 起点和终点
    int startX = 0, startY = 0;
    int endX = n - 1, endY = m - 1;

    // 如果起点或终点是墙,直接返回No(但题目保证是空地)
    if(maze[startX][startY] == '#' || maze[endX][endY] == '#') {
        cout << "No" << endl;
        return 0;
    }

    // 方向数组:左、下、右、上
    int dx[4] = {-1, 0, 1, 0};
    int dy[4] = {0, 1, 0, -1};

    // 访问标记数组
    vector<vector<bool>> visited(n, vector<bool>(m, false));

    // BFS队列
    queue<pair<int, int>> qu;
    qu.push({startX, startY});
    visited[startX][startY] = true;
    
    while (!qu.empty()) {
        auto [x, y] = qu.front();
        qu.pop();

        // 到达终点
        if(x == endX && y == endY) {
            cout << "Yes" << endl;
            return 0;
        }

        // 遍历四个方向
        for(int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
        
            // 检查新位置是否在迷宫内、是空地、且未访问
            if(nx >= 0 && nx <= endX && ny >=0 && ny <= endY 
            && visited[nx][ny] == false && maze[nx][ny] == '.') {
                qu.push({nx, ny});
                visited[nx][ny] = true;
            }    
        }
        
    }

    // BFS结束仍未到达终点
    cout << "No" << endl;
    return 0;
}

发表于 2025-10-27 10:36:29 回复(0)
n,m = map(int,input().split())
mg = []
for _ in range(n):
    mg.append(list(input()))
li = [(0,0)]
result = []
while True:
    current = li.pop()
    result.append(current)
    i,j = current
    if i == n-1 and j == m-1:
        print('Yes')
        break
    if j-1 >= 0 and mg[i][j-1] == '.' and (i,j-1) not in result:
        li.append((i,j-1))
    if i-1 >= 0 and mg[i-1][j] == '.' and (i-1,j) not in result:
        li.append((i-1,j))
    if j+1 < m and mg[i][j+1] == '.' and (i,j+1) not in result:
        li.append((i,j+1))
    if i+1 < n and mg[i+1][j] == '.' and (i+1,j) not in result:
        li.append((i+1,j))
    if not li:
        print('No')
        break
发表于 2025-10-20 17:11:09 回复(0)
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void async function () {
    // Write your code here
    while(line = await readline()){
        const [n, m] = line.split(' ').map(Number);
        const mtx = Array(n);
        for (let i = 0; i < n; i++) {
            mtx[i] = (await readline()).split('');
        }

        const visited = Array.from({length: n}, () => Array(m).fill(false));

        const dfs = function(i, j) {
            if (i < 0 || j < 0 || i >= n || j >= m || visited[i][j] || mtx[i][j] === '#') return false;
            if (i === n-1 && j === m-1) {
                return true;
            }

            visited[i][j] = true;

            if (dfs(i-1, j)) return true;
            if (dfs(i+1, j)) return true;
            if (dfs(i, j-1)) return true;
            if (dfs(i, j+1)) return true;

            return false;
        };

        console.log(dfs(0, 0) ? "Yes" : "No");
    }
}()


发表于 2025-09-26 13:15:09 回复(0)
最简单的dfs运用了
#include <iostream>
using namespace std;

int n, m;
int flag = 0;
char map[101][101]; 
bool visited[101][101] = {false};  

void dfs(int x, int y) {

    if (x < 0 || y < 0 || x >= n || y >= m) return;

    if (map[x][y] == '#' || visited[x][y]) return;

    if (x == n - 1 && y == m - 1) {
        flag = 1;
        return;
    }
    visited[x][y] = true;
    dfs(x + 1, y);  
    dfs(x - 1, y);  
    dfs(x, y + 1); 
    dfs(x, y - 1);  
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> map[i][j];
        }
    }

    dfs(0, 0);

    if (flag) cout << "Yes";
    else cout << "No";

    return 0;
}

发表于 2025-09-14 15:08:31 回复(0)
import sys

m, n = map(int, input().split())

visit = []
graph = []
for i in range(m):
    row = input()
    graph.append(row)
    visit.append([0]*n)

def go(x, y):
    visit[x][y] = 1  # 已访问
    if x==(m-1) and y == (n-1):
        return "Yes"
   
    if x+1<m and visit[x+1][y] != 1 and graph[x+1][y] != "#":
       if go(x+1, y) == "Yes":
            return "Yes"
    if x-1>0 and visit[x-1][y] != 1 and graph[x-1][y] != "#":
        if go(x-1, y) == "Yes":
            return "Yes"
    if y+1<n and visit[x][y+1] != 1 and graph[x][y+1] != "#":
        if go(x, y+1) == "Yes":
            return "Yes"
    if y-1>0 and visit[x][y-1] != 1 and graph[x][y-1] != "#":
        if go(x, y-1) == "Yes":
            return "Yes"

    return "No"
发表于 2025-09-10 21:02:10 回复(0)