首页 > 试题广场 >

走迷宫

[编程题]走迷宫
  • 热度指数:15271 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}给定一个 n \times m 的网格。你从起点 (x_s, y_s) 出发,每一次可以向上、下、左、右移动一步(若不超出边界)。某些格子上存在障碍物,无法经过。求从 (x_s, y_s) 移动到终点 (x_t, y_t) 的最少步数;若无法到达,输出 -1

输入描述:
\hspace{15pt}在一行上输入两个整数 n, m \left(1 \leqq n, m \leqq 1000\right),代表网格的行数与列数。
\hspace{15pt}在一行上输入四个整数 x_s, y_s, x_t, y_t \left(1 \leqq x_s, x_t \leqq n;\ 1 \leqq y_s, y_t \leqq m\right),代表起点与终点的坐标。
\hspace{15pt}此后 n 行,第 i 行输入一个长度为 m 的字符串 g_i,其中
\hspace{23pt}\bullet\,g_{i, j}=\texttt{,表示第 i 行第 j 列为障碍物;
\hspace{23pt}\bullet\,g_{i, j}=\texttt{,表示该格子可通行。
\hspace{15pt}保证起点所在格子可通行。


输出描述:
\hspace{15pt}输出一个整数,表示最少移动次数;若无法到达,输出 -1
示例1

输入

5 5
1 1 5 5
.....
****.
.....
**.**
.....

输出

12
示例2

输入

5 5
1 1 4 5
.....
****.
.....
**.**
.....

输出

-1
示例3

输入

5 5
1 1 5 5
.....
****.
.....
*****
.....

输出

-1
研究了好久的爆内存,发现是需要在que.push的时候就把点标记为遍历过。。。
auto ifok = [&que, &mp](int x, int y)->void{que.push(pos(x, y)); mp[x][y] = true;};

发表于 2023-08-28 19:47:25 回复(2)
import java.util.*;

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

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

    private static boolean[][] visited;

    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[] position = Arrays.stream(in.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
            int n = Integer.parseInt(line[0]);
            int m = Integer.parseInt(line[1]);
            char[][] matrix = new char[n][m];
            visited = new boolean[n][m];
            for (int i = 0; i < n; i++) {
                matrix[i] = in.nextLine().toCharArray();
            }
            int startX = position[0] - 1, startY = position[1] - 1;
            int endX = position[2] - 1, endY = position[3] - 1;

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

            while (!queue.isEmpty()) {
                cur = queue.poll();
                int curX = cur.x;
                int curY = cur.y;
                int curStep = cur.step;

                if (curX == endX && curY == endY) {
                    System.out.println(curStep);
                    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] == '.') {
                        visited[dx][dy] = true;
                        queue.add(new Point(dx, dy, curStep + 1));
                    }
                }
            }

            if (!isArrive) {
                System.out.println(-1);
            }
        }
    }
}

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

发表于 2025-12-08 16:24:23 回复(0)
这个题是bfs经典的迷宫题型,解法如下:
使用队列存储,加一个标记数组,以及所需要的方向数组(注意有的是8个方向,这里只有上下左右四个方向)
这里需要记录终点到起点的距离,所以在标记的同时记录位置,具体代码如下:
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

//bfs使用队列
int main() {
    int n, m;
    cin >> n >> m;
    int start_X, start_Y, end_X, end_Y;
    cin >> start_X >> start_Y >> end_X >> end_Y;
    vector<string>  gi(n);
    for (int i = 0; i < n; i ++) {
        cin >> gi[i];
    }

    //如果开始或者结束存在障碍,直接返回
    if (gi[start_X - 1][start_Y - 1] == '*' || gi[end_X - 1][end_Y - 1] == '*') {
        cout << "-1" << endl;
        return 0;
    }

    //距离数组标记,同时记录距离起点的距离
    vector<vector<int>> visited(n, vector<int>(m, -1));

    //初始化方向数组
    int dx[4] = {-1, 0, 1, 0};
    int dy[4] = {0, -1, 0, 1};

    //初始化队列
    queue<pair<int, int>> q;
    q.push({start_X - 1, start_Y - 1});
    visited[start_X - 1][start_Y - 1] = 0;

    int count_num = 0;
    while (!q.empty()) {
        auto[x, y] = q.front();
        q.pop();

        if(x == end_X - 1 && y == end_Y - 1) {
            cout << visited[x][y] << endl;
            return 0;
        }

        //遍历方向数组
        for (int i = 0; i < 4; i ++) {
            int nx = x + dx[i];
            int ny = y + dy[i];

            if (nx >= 0 && nx < n && ny >= 0 && ny < m &&
                    visited[nx][ny] == -1 && gi[nx][ny] == '.') {
                        q.push({nx, ny});
                        //新的位置的距离等于旧的位置距离加1
                        visited[nx][ny] = visited[x][y] + 1;
            }
        }
    }
    cout << "-1" << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")


发表于 2025-10-27 22:03:31 回复(0)
from collections import deque
class Maze:
    def __init__(self):
        self.n, self.m = list(map(int, input().split(" ")))
        self.start_y, self.start_x, self.end_y, self.end_x = list(
            map(lambda x: int(x)-1, input().split(" ")))
        self.grid = [['\0' for _ in range(self.m)]
                     for _ in range(self.n)]
        for i in range(self.n):
            self.grid[i] = list(str(input()))
        self.visited = [[False for _ in range(self.m)]
                        for _ in range(self.n)]
        self.direction = [(1, 0), (0, 1), (-1, 0), (0, -1)]
    def bfs(self):
        queue = deque([(self.start_x, self.start_y, 0)])
        while queue:
            curr_x, curr_y, curr_len = queue.popleft()
            if self.visited[curr_y][curr_x]:
                continue
            self.visited[curr_y][curr_x] = True
            if (curr_y, curr_x) == (self.end_y, self.end_x):
                return curr_len
            for dx, dy in self.direction:
                nx = curr_x + dx
                ny = curr_y + dy
                if ((0 <= nx < self.m) and
                    (0 <= ny < self.n) and
                        self.grid[ny][nx] == "." and
                        not self.visited[ny][nx]):
                    nl = curr_len+1
                    queue.append((nx, ny, nl))
        return -1
if __name__ == "__main__":
    m = Maze()
    print(m.bfs())
发表于 2025-10-10 09:15:10 回复(0)
以下代码已通过所有用例,是AI帮我修复了bug,整体思路是没问题的
//AI是真牛逼啊,直接帮你把bug改好了,然后回顾你一下你的问题点在哪把
//错就错在你没把struct position用指针的别名来用,导致没有用指针的指针
typedef struct position {  //要有名字才能识别next
    int x;
    int y;  
    int bushu;
    struct position *next;
} position,*position_link;  //为什么上面的next没有识别到这个position是因为这个position是在后面的

// 入队列函数 - 修正版
void queue_push(position** queue, position temp) {
    position* new_node = (position*)malloc(sizeof(position)); //不可以直接赋值局部变量会消失
    new_node->x = temp.x;
    new_node->y = temp.y;
    new_node->bushu = temp.bushu;
    new_node->next = NULL;
    
    if (*queue == NULL) {
        *queue = new_node;
    } else {
        position* p = *queue;
        while (p->next != NULL) {  // 找到最后一个节点
            p = p->next;
        }
        p->next = new_node;  // 在末尾添加新节点
    }
}

// 出队列函数 - 修正版
position queue_pop(position** queue) {   //指针的指针才能修改传递的值
    if (*queue == NULL) {
        position empty = {-1, -1, -1, NULL};
        return empty;
    }
    
    position* temp = *queue;
    position result = *temp;
    *queue = (*queue)->next;
    free(temp);
    return result;
}

// 检查队列是否为空
int is_queue_empty(position* queue) {
    return queue == NULL;
}

int main() {
    int n, m;
    scanf("%d %d", &n, &m);

    int start_x, start_y;
    int end_x, end_y;
    scanf("%d %d %d %d", &start_x, &start_y, &end_x, &end_y);

    // 初始化迷宫地图
    char **migong_map = malloc(sizeof(char*) * (n + 1));
    for(int i = 0; i <= n; i++) {
        migong_map[i] = malloc(sizeof(char) * (m + 1));
    }

    // 读取迷宫
    for(int i = 1; i <= n; i++) {
        scanf("%s", migong_map[i]);
        // 边界处理
        for(int j = m; j > 0; j--) {
            migong_map[i][j] = migong_map[i][j - 1];
        }
        migong_map[i][0] = '*';
    }

    // 第0行设置为墙
    for(int i = 0; i <= m; i++) {
        migong_map[0][i] = '*';
    }

    // BFS开始
    position* queue = NULL;  // 初始化队列
    
    position d1 = {
        .x = start_x,
        .y = start_y,
        .bushu = 0,
        .next = NULL
    };
    queue_push(&queue, d1);

    int min_bushu = n * m;
    
    while (!is_queue_empty(queue)) {  // 使用队列空判断
        position front = queue_pop(&queue);
        
        // 检查是否到达终点
        if (front.x == end_x && front.y == end_y) {  // 修正:使用 &&
            if (front.bushu < min_bushu) {
                min_bushu = front.bushu;
            }
            // 找到终点后可以继续搜索更短路径,或者直接break
        }

        // 检查是否为空标记(如果队列真的空了,循环条件会处理)
        
        // 上下左右移动
        // 注意:边界检查修正
        if (front.x - 1 >= 1 && migong_map[front.x - 1][front.y] == '.') { // 往上
            position temp = {
                .x = front.x - 1,
                .y = front.y,
                .bushu = front.bushu + 1,
                .next = NULL
            };
            queue_push(&queue, temp);
            migong_map[temp.x][temp.y] = '*';  // 立即标记为已访问
        }
        if (front.y - 1 >= 1 && migong_map[front.x][front.y - 1] == '.') { // 往左
            position temp = {
                .x = front.x,
                .y = front.y - 1,
                .bushu = front.bushu + 1,
                .next = NULL
            };
            queue_push(&queue, temp);
            migong_map[temp.x][temp.y] = '*';
        }
        if (front.x + 1 <= n && migong_map[front.x + 1][front.y] == '.') { // 往下
            position temp = {
                .x = front.x + 1,
                .y = front.y,
                .bushu = front.bushu + 1,
                .next = NULL
            };
            queue_push(&queue, temp);
            migong_map[temp.x][temp.y] = '*';
        }
        if (front.y + 1 <= m && migong_map[front.x][front.y + 1] == '.') { // 往右
            position temp = {
                .x = front.x,
                .y = front.y + 1,
                .bushu = front.bushu + 1,
                .next = NULL
            };
            queue_push(&queue, temp);
            migong_map[temp.x][temp.y] = '*';
        }
    }

    // 输出结果
    if (min_bushu == n * m) {
        printf("%d", -1);
    } else {
        printf("%d", min_bushu);
    }
    
    // 释放内存
    for(int i = 0; i <= n; i++) {
        free(migong_map[i]);
    }
    free(migong_map);
    
    return 0;
}


发表于 2025-10-05 16:37:24 回复(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 [xs, ys, xt, yt] = (await readline()).split(" ").map(Number);
        const mtx = Array(n);

        if (xs === xt && ys === yt) {
            console.log(1);
            continue;
        }

        for (let i = 0; i < n; i++) {
            mtx[i] = (await readline()).split("");
        }

        const visited = Array.from({ length: n }, () => Array(m).fill(false));
        visited[xs-1][ys-1] = true;
        const queue = [[xs - 1, ys - 1]];
        let steps = 0;
        let reachable = false;
        let front = 0
        while (front < queue.length) {
            const levelSize = queue.length - front;
            for (let i = 0; i < levelSize; i++) {
                let [x, y] = queue[front++];
                
                if (x - 1 >= 0 && mtx[x - 1][y] === "." && !visited[x - 1][y]) {
                    if (x - 1 === xt - 1 && y === yt - 1) {
                        reachable = true;
                        steps++;
                        break;
                    }
                    queue.push([x - 1, y]);
                    visited[x-1][y] = true;
                }
                if (x + 1 < n && mtx[x + 1][y] === "." && !visited[x + 1][y]) {
                    if (x + 1 === xt - 1 && y === yt - 1) {
                        reachable = true;
                        steps++;
                        break;
                    }
                    queue.push([x + 1, y]);
                    visited[x+1][y] = true;
                }
                if (y - 1 >= 0 && mtx[x][y - 1] === "." && !visited[x][y - 1]) {
                    if (x === xt - 1 && y - 1 === yt - 1) {
                        reachable = true;
                        steps++;
                        break;
                    }
                    queue.push([x, y - 1]);
                    visited[x][y-1] = true;
                }
                if (y + 1 < m && mtx[x][y + 1] === "." && !visited[x][y + 1]) {
                    if (x === xt - 1 && y + 1 === yt - 1) {
                        reachable = true;
                        steps++;
                        break;
                    }
                    queue.push([x, y + 1]);
                    visited[x][y+1] = true;
                }
            }

            if (reachable) {
                break;
            }

            steps++;
        }

        console.log(reachable ? steps : -1);
    }
})();

发表于 2025-09-26 14:46:42 回复(0)

边界条件放前面

import java.util.*;

public class Main {
    public static final int[][] DIRECTIONS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int sizeX = in.nextInt();
        int sizeY = in.nextInt();

        int startX = in.nextInt() - 1;
        int startY = in.nextInt() - 1;
        int endX = in.nextInt() - 1;
        int endY = in.nextInt() - 1;

        in.nextLine();
        char[][] graph = new char[sizeX][sizeY];
        for(int i = 0; i < sizeX; i++) {
            String tmp = in.nextLine();
            for(int j = 0; j < sizeY; j++) {
                graph[i][j] = tmp.charAt(j);
            }
        }

        int result = bfs(startX, startY, endX, endY, graph, sizeX, sizeY);

        System.out.println(result);
    }

    private static int bfs(int startX, int startY, int endX, int endY, char[][] graph, int sizeX, int sizeY) {
        if(graph[startX][startY] == '*' || graph[endX][endY] == '*') {
            return -1;
        }

        boolean[][] visited = new boolean[sizeX][sizeY];
        Queue<int[]> queue = new LinkedList<>();
        int step = 0;

        queue.offer(new int[]{startX, startY, step});
        visited[startX][startY] = true;

        while(!queue.isEmpty()) {
            int[] cur = queue.poll();
            int curX = cur[0];
            int curY = cur[1];
            int curStep = cur[2];

            if(curX == endX && curY == endY) {
                return curStep;
            }

            for(int[] temp : DIRECTIONS) {
                int newX = curX + temp[0];
                int newY = curY + temp[1];

                if(newX < sizeX && newX >= 0 && newY < sizeY && newY >=0 && visited[newX][newY] == false && graph[newX][newY] != '*') {
                    queue.offer(new int[]{newX, newY, curStep + 1});
                    visited[newX][newY] = true;
                    step++;
                }               
            }
        }

        return -1;
    }
}
发表于 2025-09-17 17:59:53 回复(0)
from collections import deque

n,m = map(int , input().split())
xs,ys,xt,yt = map(int, input().split())
xs,ys,xt,yt = xs-1,ys-1,xt-1,yt-1
maze = []
for _ in range(n):
    row = list(input())
    maze.append(row)

def play_maze(n,m,xs,ys,xt,yt,maze):
    visited= [[False]*m for _ in range(n)]
    visited[xs][ys]=True
    q = deque()
    q.append((xs,ys,0)) # x,y,steps
    directions = [(1,0),(-1,0),(0,1),(0,-1)]
    while q:
        x,y,steps = q.popleft()
        if (x,y)==(xt,yt):
            return steps
        for dx,dy in directions:
            nx ,ny = x+dx, y+dy
            if 0<=nx<n and 0<=ny<m and maze[nx][ny]=='.' and not visited[nx][ny]:
                visited[nx][ny]=True
                # 注意这里不能写steps +=1,再append(steps),会导致不同方向之间的初始steps会不同
                q.append((nx,ny,steps+1))
    return -1

print(play_maze(n,m,xs,ys,xt,yt,maze)) 

发表于 2025-08-14 15:17:53 回复(0)
import sys
from collections import deque


def main():
    n, m = map(int, sys.stdin.readline().split())
    xs, ys, xt, yt = map(int, sys.stdin.readline().split())
    grid = [sys.stdin.readline().strip() for _ in range(n)]

    # 转换为 0-based 或保持 1-based,根据题目要求调整
    xs -= 1
    ys -= 1
    xt -= 1
    yt -= 1

    if grid[xs][ys] == "*"&nbs***bsp;grid[xt][yt] == "*":
        print(-1)
        return

    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    visited = [[-1 for _ in range(m)] for __ in range(n)]
    q = deque()
    q.append((xs, ys))
    visited[xs][ys] = 0

    while q:
        x, y = q.popleft()
        if x == xt and y == yt:
            print(visited[x][y])
            return
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if (
                0 <= nx < n
                and 0 <= ny < m
                and grid[nx][ny] == "."
                and visited[nx][ny] == -1
            ):
                visited[nx][ny] = visited[x][y] + 1
                q.append((nx, ny))

    print(-1)


if __name__ == "__main__":
    main()

发表于 2025-06-21 15:17:40 回复(0)
也出现了爆内存问题,因为每一次visit点的时候要标记为visited,否则会重复访问,导致队列膨胀;其中visited的标记也可以使用dictionary,但更耗内存,因为要格外存储哈希值,value等元素;另外,存储grid的时候可以将符号改成true/false,或者改成0-based索引(从0开始是第一位),更加节省内存空间;这道题因为是单点到单点的最短距离,bfs更适合。

import sys
from collections import deque

def bfs(n,m,xs,ys,xt,yt, grid):
queue = deque()
visited = [[False for _ in range(m+1)] for _ in range(n+1)]
queue.append((xs,ys,0)) #初始化visited的点,也可以用dictionary
visited[xs][ys] = True

direction = [(-1,0),(1,0),(0,1),(0,-1)]

while queue:
u,v,w = queue.popleft()

if (u,v) == (xt,yt): #找到想要的点
return w

for i in direction: #遍历和当前点相连的点
(nextx,nexty) = (u+i[0], v+i[1])

if 1<= nextx <= n and 1<= nexty <= m and visited[nextx][nexty] == False and grid[nextx][nexty] == '.':
#需要标记visited,否则会爆内存
visited[nextx][nexty] = True
queue.append((nextx,nexty,w+1))
return -1

n, m = map(int, sys.stdin.readline().split())
xs, ys, xt, yt = map(int, sys.stdin.readline().split())
grid = [''] * (n + 1) # 1-based索引
for i in range(1, n + 1):
# 1-based索引,每一个grid的string list第一位为空
grid[i] = ' '+sys.stdin.readline().strip()

step = bfs(n,m,xs,ys,xt,yt, grid)
print(step)

发表于 2025-05-18 02:43:01 回复(0)
n,m = map(int,input().split())
x0,y0,xend,yend = map(lambda x:int(x) - 1,input().split())
start = (x0,y0)
end = (xend,yend)
g = [list(input()) for _ in range(n)]
# print(g,start,end)
###############
from collections import deque
q = deque([(x0,y0,0)])

if g[x0][y0] == "*" or g[xend][yend] == "*":
    print(-1)
else:
    found = 0
    while q:
        x,y,d = q.popleft()
        if (x,y) == (xend,yend):
            print(d)
            found = 1
            break
        directions = [(1,0),(0,1),(0,-1),(-1,0)]
        for dx,dy in directions:
            x_next,y_next = x + dx, y + dy
            if x_next < 0 or x_next >= n or y_next < 0 or y_next >= m or g[x_next][y_next] == "*":
                continue
            q.append((x_next,y_next,d+1))
            g[x_next][y_next] = "*"
    if not found:
        print(-1)

           
       

发表于 2025-05-14 11:00:37 回复(0)
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

typedef pair<int,int> PII;
vector<vector<int>> graph;
vector<vector<int>> dist;
queue<PII> q;

int manhattanDistance(const PII& p1, const PII& p2) {
    return abs(p1.first - p2.first) + abs(p1.second - p2.second);
}

void bfs(PII s,PII t)
{
    int dx[] = {0, 0, 1, -1};
    int dy[] = {1, -1, 0, 0};
    q.push(s);
    graph[s.first][s.second]=-1;
    dist[s.first][s.second]=0;
    while(!q.empty())
    {
        PII cur=q.front();
        q.pop();
        if(manhattanDistance(cur, t)==0) break;
        for(int i=0;i<4;i++)
        {
            int newx=cur.first+dx[i];
            int newy=cur.second+dy[i];
            if((newx>graph.size()-1 )||(newy>graph[1].size()-1) ||newx<=0 ||newy<=0) continue;
            if(graph[newx][newy]==1 ||graph[newx][newy]==-1)       
            continue;
            PII temp={newx,newy};
            q.push(temp);
            graph[newx][newy]=-1;
            dist[newx][newy]=dist[cur.first][cur.second]+1;
        }
    }
}

int main() {
    int n,m;cin>>n>>m;
    graph.resize(n+1,vector<int>(m+1,0));
    dist.resize(n+1,vector<int>(m+1,-1));
    int xs,ys,xt,yt;cin>>xs>>ys>>xt>>yt;
    PII S={xs,ys};PII T={xt,yt};
    for(int i=1;i<n+1;i++)
    {
        for(int j=1;j<m+1;j++)
        {
            char temp;cin>>temp;
            if(temp=='*') graph[i][j]=1;
            else graph[i][j]=0;
        }
    }
    bfs(S, T);
    cout<<dist[T.first][T.second];
    return 0;
}
发表于 2025-04-21 11:34:33 回复(0)
#include <iostream>
using namespace std;
int x,y;//current position
int sch[110][110];//have searched(1) or not(0)
int p,q;//terminal position
int map[1100][1100];//0-boundary;1-vailable;2-barrier
int minstep=100000;//minimum step
void dfs(int x,int y,int step){
    if (step >= minstep) return;
    if(x==p&&y==q){//arrive
       
        if(step<minstep){
            minstep=step;
           
        }
        return;
    }
    //clockwise search
    //right
    if(map[x][y+1]==1&&sch[x][y+1]==0){
        sch[x][y+1]=1;
        dfs(x,y+1,step+1);
        sch[x][y+1]=0;
    }
    //down
    if(map[x+1][y]==1&&sch[x+1][y]==0){
        sch[x+1][y]=1;
        dfs(x+1,y,step+1);
        sch[x+1][y]=0;
    }
    //left
    if(map[x][y-1]==1&&sch[x][y-1]==0){
        sch[x][y-1]=1;
        dfs(x,y-1,step+1);
        sch[x][y-1]=0;
    }
    //up
    if(map[x-1][y]==1&&sch[x-1][y]==0){
        sch[x-1][y]=1;
        dfs(x-1,y,step+1);
        sch[x-1][y]=0;
    }
    return;
}
int main() {
    int n,m;
    int startx,starty;
    cin>>n>>m;
    cin>>startx>>starty>>p>>q;
    string grid;
    for(int i=1;i<=n;i++){
        cin>>grid;
        for(int j=1;j<=m;j++){
            if(grid[j-1]=='*'){
                map[i][j]=2;
            }
            else if(grid[j-1]=='.'){
                map[i][j]=1;
            }

        }
    }
    sch[startx][starty]=1;
    dfs(startx,starty, 0);
    if(minstep==100000){
        cout<<"-1"<<endl;
    }
    else{
        cout<<minstep<<endl;
    }

}
// 64 位输出请用 printf("%lld")
发表于 2025-04-10 18:14:28 回复(0)
import sys
from collections import deque

try:
    while True:
        n, m = map(int, sys.stdin.readline().split())

        start_x, start_y, end_x, end_y = map(int, sys.stdin.readline().split())

        grid = []
        for _ in range(n):
            line = sys.stdin.readline().strip()
            grid.append(line)

        direction = [(1,0), (0, 1), (-1, 0), (0 , -1)]
        visited = [[False] * m for _ in range(n)]
        queue = deque()
        queue.append((start_x - 1, start_y - 1, 0))
        visited[start_x - 1][start_y - 1] = True
        find_result = False
        while queue:
            x, y, step = queue.popleft()
            if x == end_x - 1 and y == end_y - 1:
                print(step)
                find_result = True

            else:
                for dx, dy in direction:
                    next_x, next_y = dx + x, dy + y
                    if 0 <= next_x < n and 0 <= next_y < m and grid[next_x][next_y] != "*" and not visited[next_x][next_y]:
                        visited[next_x][next_y] = True
                        queue.append((next_x, next_y, step + 1))

        if not find_result:
            print(-1)

except:
    pass

发表于 2025-03-06 16:03:38 回复(0)
系统默认1000次不够用,需要改多点
import sys
sys.setrecursionlimit(3000)
n , m = map(int,input().split())
res = []
mp = []
jey = []
global depth
depth = 0
def bfs(mp,edi,edj,bnow,depth,visited):
    if len(bnow) == 0:
        jey.append(0)
        return
    newb = []
    depth += 1
    for p in bnow:
        if p[0] == edi and p[1] == edj :
            jey.append(1)
            return
        di = [1,0,-1,0]
        dj = [0,1,0,-1]
        for k in range(4):
            t1 = p[0] + di[k]
            t2 = p[1] + dj[k]
            if 0 <= t1 < n and 0 <= t2 < m and mp[t1][t2] == '.' and visited[t1][t2] == 0 :
                visited[t1][t2] = 1
                newb.append((t1,t2))
    res.append(depth)
    bfs(mp,edi,edj,newb,depth,visited)

now = []    
l = list(map(int,input().split()))
sti = l[0] - 1
stj = l[1] - 1
edi = l[2] - 1
edj = l[3] - 1
now.append((sti,stj))
visted = [[0 for j in range(m)]for i in range(n)]
visted[sti][stj] = 1
for i in range(n):
    mp.append(input())
k = bfs(mp,edi,edj,now,depth,visted)
if not jey[0]:
    print('-1')
else:
    print(res[-1])
发表于 2024-12-04 18:49:45 回复(0)
这个题目说好的起点不存在障碍物,结果最后一个实例起点就有障碍物,害我想了半天,另外的本题尽量使用bfs
from copy import copy
import copy
def bfs(a1,b1,a2,b2,pathmap):
    queue=[[a1,b1]]
    step=0
    while queue:
        queue1=[]
        for item in queue:
            for i, j in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
                if (0<=item[0]+i<=len(pathmap)-1)&(0<=item[1]+j<=len(pathmap[0])-1):
                    a=item[0]+i;b=item[1]+j
                    if (pathmap[a][b]!=1)&(pathmap[a][b]!=-1):
                        queue1.append([a,b])
                        pathmap[a][b]=1
                    if (a==a2)&(b==b2):
                        return step+1

        step+=1
        queue=copy.deepcopy(queue1)
    return -1

n,m=map(int,input().split())
a1,b1,a2,b2=map(int,input().split())
map=[]
for _ in range(n):
    map.append(list(input()))
pathmap=[]
for i in range(n):
    temp=[]
    for j in range(m):
        if map[i][j]=='.':
            temp.append(0)
        else:
            temp.append(-1)
    pathmap.append(temp)

if (pathmap[a2-1][b2-1]==-1)|(pathmap[a1-1][b1-1]==-1):
    short=-1
else:
    pathmap[a1 - 1][b1 - 1] = 1
    short=bfs(a1-1,b1-1,a2-1,b2-1,pathmap)
print(short)

发表于 2024-11-26 15:04:08 回复(0)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
    int x;
    int y;
}node; //坐标系

int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};

int bfs(char** map,int xs,int ys,int xt, int yt,int n,int m){
    int f=0,r=0;
    int dist[n+1][m+1];
    node q[(n+1)*(m+1)];
    for (int i=0;i<n+1;i++) {
         for(int j=0;j<m+1;j++) {
               dist[i][j]=-1;
         }
    }
    q[r].x=xs,q[r].y=ys;
    dist[q[r].x][q[r].y]=0,r++;
    while (f<r) {
         int x=q[f].x,y=q[f].y;
         if (x==xt&&y==yt) {
             return dist[q[f].x][q[f].y];
         }
         else{
            for (int i=0; i<4; i++) {
                 int nx=x+dx[i],ny=y+dy[i];
                 if (nx<=n&&ny<=m&&nx>=1&&ny>=1&&map[nx][ny]=='.'&&dist[nx][ny]==-1) {
                       dist[nx][ny]=dist[q[f].x][q[f].y]+1;
                       q[r].x=nx,q[r].y=ny,r++;
                 }
            }
         }
         f++;
    }
    return -1;
}

int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    int xs, ys, xt, yt;
    scanf("%d %d %d %d", &xs, &ys, &xt, &yt);
    getchar();
    char** map=(char**)malloc(sizeof(char*)*(n+1));
    for (int i=0; i<n+1; i++) {
           map[i]=(char*)malloc(sizeof(char)*(m+1));
    }
    for(int i=1;i<n+1;i++){
        for(int j=1;j<m+1;j++){
            scanf("%c",&map[i][j]);
        }
        getchar();
    }
    if (map[xt][yt]=='*') {
        printf("-1");
    }
    else {
        printf("%d",bfs(map,xs,ys,xt,yt,n,m));
    }
    return 0;
}

发表于 2024-11-21 19:22:26 回复(0)
邻接矩阵+bfs
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define max 2000000000
typedef struct{
    int x,y;
}node;
typedef struct{
    node *location;
    int begin,end,maxsize;
}quene;
quene Initque(){
    quene Q;
    Q.maxsize=10000;
    Q.location=(node *)malloc(sizeof(node)*Q.maxsize);
    Q.begin=Q.end=0;
    return Q;
}
int isfull(quene *Q){
    if((Q->end-Q->begin+Q->maxsize)%Q->maxsize==Q->maxsize-1) return 1;
    return 0;
}
void expandque(quene *Q){
    Q->maxsize+=100;
    Q->location=(node *)realloc(Q->location,sizeof(node)*Q->maxsize);
}
void putin(quene *Q,int x,int y){
    if(isfull(Q)) expandque(Q);
    Q->location[Q->end].x=x;
    Q->location[Q->end].y=y;
    Q->end=(Q->end+1)%Q->maxsize;
}
node deque(quene *Q){
    node temp=Q->location[Q->begin];
    Q->begin=(Q->begin+1)%Q->maxsize;
    return temp;
}
int isempty(quene *Q){
    if(Q->begin==Q->end) return 1;
    return 0;
}
typedef struct{
    char **data;
}map;
map Init(int n,int m){
    map M;
    M.data=malloc(sizeof(char *)*n);
    for(int i=0;i<n;i++){
        M.data[i]=malloc(sizeof(char)*m);
    }
    return M;
}
void Insert(map *m,int len,char *s){
    for(int j=0;j<strlen(s);j++){
        m->data[len][j]=s[j];
    }
}
int dfs(map *m,const int nlen,const int mlen,int x1,int y1,int x2,int y2){
    if(m->data[x1][y1]=='*') return -1;
    quene Q=Initque();
    bool hasvisit[nlen][mlen];
    int path[nlen][mlen];
    for(int i=0;i<nlen;i++){
        for(int j=0;j<mlen;j++){
            path[i][j]=max;
            hasvisit[i][j]=false;
        }
    }
    hasvisit[x1][y1]=true;
    path[x1][y1]=0;
    putin(&Q,x1,y1);
    int dir[][2]={{1,0},{0,1},{-1,0},{0,-1}};
    while(!isempty(&Q)){
        node temp=deque(&Q);
        if(temp.x==x2&&temp.y==y2) break;
        for(int i=0;i<4;i++){
            int nx=temp.x+dir[i][0];
            int ny=temp.y+dir[i][1];
            if(nx>=0&&nx<nlen&&ny>=0&&ny<mlen&&m->data[nx][ny]!='*'&&!hasvisit[nx][ny]){
                hasvisit[nx][ny]=true;
                putin(&Q,nx,ny);
                int templen=path[temp.x][temp.y]+1;
                path[nx][ny]=templen<path[nx][ny] ? templen:path[nx][ny];
            }
        }
    }
    if(path[x2][y2]!=max) return path[x2][y2];
    return -1;
}
int main() {
    int a, b,x1,x2,y1,y2;
    scanf("%d %d",&a,&b);
    scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
    char s[b+1];
    map m=Init(a,b);
    for(int i=0;i<a;i++){
        scanf("%s",s);
        Insert(&m,i,s);
    }
    printf("%d\n",dfs(&m,a,b,x1-1,y1-1,x2-1,y2-1));
    return 0;
}

发表于 2024-10-05 19:11:10 回复(0)
有没有大佬帮忙看一下错哪里了啊啊啊,只能通过两个用例
#include <iostream>
using namespace std;

int p,q,m,n,mmin=9999999;
string a[1000][1000];//.表示空地,*表示障碍物
int v[1000][1000];//0表示未访问,1表示访问
void dfs(int x, int y, int step) {
    if (x==p && y==q){
        if(step < mmin){
            mmin = step;
        } 
        return;
    }   
    //顺时针试探
    //右
    if(a[x][y+1] == "." && v[x][y+1]==0){
        v[x][y+1]=1;
        dfs(x, y+1, step+1);
        v[x][y+1]=0;
    }
    //下
    if(a[x+1][y]=="." && v[x+1][y]==0){
        v[x+1][y]=1;
        dfs(x+1, y, step+1);
        v[x+1][y]=0;
    }
    //左
    if(a[x][y-1]=="." && v[x][y-1]==0){
        v[x][y-1]=1;
        dfs(x, y-1, step+1);
        v[x][y-1]=0;
    }
    //上
     if(a[x-1][y]=="." && v[x-1][y]==0){
        v[x-1][y]=1;
        dfs(x-1, y, step+1); 
        v[x-1][y]=0;
    }
    return;    
}

int main(){
    int startx, starty;
    cin >> n >> m;
    cin >> startx >> starty >> p >> q;
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            cin >> a[i][j];
        }
    }
    v[startx][starty] = 1; 
    dfs(startx, starty, 0);
    if (mmin == 9999999) {
        cout << -1;
    } else {
        cout << mmin;
    }
    return 0;
}


发表于 2024-08-17 02:22:23 回复(0)
c语言,常规思路,看成一个图+bfs的过程
#include <stdio.h>
#include <stdlib.h>
//邻接矩阵 + bfs
typedef struct graph{
    int n;
    int m;
    int** datas;
}graph;
void init_graph(graph* g,int n,int m){
    g->n = n;
    g->m = m;
    g->datas = malloc(sizeof(int *)*n);
    for(int i = 0 ; i < n;i++){
        g->datas[i] = malloc(sizeof(int)*m);
    }
}

int add_edge(graph* g,int start,int end,char c){
    if('.' == c){
        g->datas[start][end] = 0;
    } else if('*' == c) {
         g->datas[start][end] = 1;
    }
    return 1;
}

typedef struct node{
    int x;
    int y;
    int layer;
    struct node* next;
}node;

typedef struct queue{ //head头节点,tail指向最后一个节点,如果超时,可以尝试使用顺序表来定义队列
    node* head;
    node* tail;
}queue;

void init_queue(queue* q){
    q->head = malloc(sizeof(node));
    q->head->next = NULL;
    q->tail =  q->head;
}

int empty_queue(queue* q){
    if(q->head == q->tail){
        return 1;
    } else {
        return 0;
    }
}

void in_queue(queue* q,int x,int y,int layer){
    node* no = malloc(sizeof(node));
    no->x = x;
    no->y = y;
    no->layer = layer;
    no->next = NULL;
    q->tail->next = no;
    q->tail = no;
}
int de_queue(queue* q,node** ret){
    if(q->head->next != NULL){
        *ret = q->head->next;
        q->head->next = (*ret)->next;
        if(*ret == q->tail){
            q->tail = q->head;
        }
        return 1;
    } else {
        return 0;
    }
}

int bfs(graph* g,int startx,int starty,int endx,int endy){
    //将当前位置入栈
    queue q;
    node* cur;
    init_queue(&q);
    in_queue(&q,startx,starty, 0);
    //标记cur节点为已经访问,-1表示该位置已经访问
    g->datas[startx][starty] = -1;
    while(!empty_queue(&q)){
        de_queue(&q, &cur);
        //判断是否是目标节点
        if(cur->x == endx && cur->y == endy){
            return cur->layer;
        }

        //将该位置上下左右没有障碍物的路径加入栈
        if((cur->x - 1) >= 0 && g->datas[cur->x-1][cur->y] == 0){
            g->datas[cur->x - 1][cur->y] = -1;
            in_queue(&q, cur->x - 1, cur->y, cur->layer + 1);
        }
        if((cur->x + 1) < g->n && g->datas[cur->x + 1][cur->y] == 0){
            g->datas[cur->x + 1][cur->y] = -1;
            in_queue(&q, cur->x + 1, cur->y, cur->layer + 1);
        }

        if((cur->y - 1) >= 0 && g->datas[cur->x][cur->y - 1] == 0){
            g->datas[cur->x][cur->y-1] = -1;
            in_queue(&q, cur->x, cur->y-1, cur->layer + 1);
        }
        if((cur->y + 1) < g->m && g->datas[cur->x][cur->y + 1] == 0){
            g->datas[cur->x][cur->y+1] = -1;
            in_queue(&q, cur->x, cur->y+1, cur->layer + 1);
        }
        free(cur);
    }
    return -1;
}



int main() {
    int n,m;
    scanf("%d%d",&n,&m);
    graph g;
    init_graph(&g, n,m);
    char c = 0;

    int startx,starty,endx,endy;
    scanf("%d%d%d%d",&startx,&starty,&endx,&endy);
    scanf("%c",&c); //取换行符
    for(int i = 0 ; i < n; i++){
        for(int j = 0 ; j < m;j++){
            scanf("%c",&c);
            add_edge(&g, i, j, c);
        }
        scanf("%c",&c);//取换行符
    }
    int result = bfs(&g, startx - 1, starty-1, endx-1, endy -1);
    printf("%d",result);
    return 0;
}


编辑于 2024-02-20 14:12:44 回复(0)