信息学奥赛一本通1255:迷宫问题

191 阅读1分钟

信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)

解析:迷宫问题(信息学奥赛一本通-T1255)_哔哩哔哩_bilibili

因为要求输出最短路径上的坐标,因为这条路线不一定是一个直线,所以我们可以用链表来存储这条路径上的所有坐标。如下图:

因为是55的地图,因此对于每一个坐标我们都可以通过 行5+列的方式求出。

image.png

#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
typedef pair<int, int> PII;
queue<PII> q;
int dis[5][5];
int maze[5][5];
vector<PII> v;
int pre[30];
int dx[4] = { -1,0,1,0 }; int dy[4] = { 0,1,0,-1 };


void show(int n)
{
    if (!pre[n])
    {
        cout << "(0, 0)" << endl;
        return;
    }
    show (pre[n]);
    cout << "(" << pre[n] / 5 << ", " << pre[n] % 5 << ")" <<endl;
}

void bfs(int maze[5][5])
{
    // 起始位置加入队头
    q.push({ 0,0 });
    // 初始化所有路径为没走过
    memset(dis, -1, sizeof dis);
    // 把起始位置标记为走过
    dis[0][0] = 0;

    while (!q.empty())
    {
        // 弹出队头
        PII t = q.front();
        q.pop();

        // 把其他元素加入队层
        for (int i = 0; i < 4; i++)
        {
            
            int x = t.first + dx[i], y = t.second + dy[i];              // 开始移动
            if (x < 0 || x >= 5 || y < 0 || y >= 5) continue; // 确保不越界
            if (dis[x][y] != -1) continue;                  // 已经走过的不能再走
            if (maze[x][y] == 1) continue;                  // 路障不能走
            dis[x][y] = dis[t.first][t.second] + 1;         // 下一个位置=当前位置+1

            pre[5 * x + y] = 5 * t.first + t.second;
            q.push({ x,y });

        }
    }
    show(24);最后一个位置的坐标   4*5+4
}
int main()
{
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            cin >> maze[i][j];
        }
    }
    bfs(maze);
    cout << "(4, 4)" << endl;
 
    return 0;
}