首页 > 试题广场 >

走迷宫

[编程题]走迷宫
  • 热度指数:15289 时间限制: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
以下代码已通过所有用例,是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)
#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)