分支限界法-最少步数走出迷宫

问题描述:
用户从屏幕输入m,n表示一个m*n的迷宫,0表示空地,1表示墙,给定起点的行,列;给定终点的行,列;输出最少到达目标的步数;
示例输入:
4 4
0 0 1 0
0 1 0 0
0 0 0 1
0 0 0 0
0 0
2 2
样例输出:
5

问题分析:
1.根据分支限界法基本思想(详见上篇分支限界博客)
(1)分支:当前位置每次有四种可能的走法上下左右,可分四个子状态;
(2)限界:若为墙,则不能走;若走过,则不能走;
2.确定输入输出:
迷宫的行列M,N;
迷宫的初始状态;
起点的坐标;
终点的坐标;
输出一个最小步数;
3.确定所需数据结构:
二维数组表示迷宫;
队列存放路径;
4.确定状态值:
迷宫中-2墙(为了计算与表示方便,将墙1置为-2,若为正常的额1表示,则需要多余的数据结构来记录某点是否走过),-1表示未走过,其余数字值表示从起点至当前位置所需步数;
方向:0-up, 1-down, 2-left, 3-right;

代码展示:

#include <iostream>
#include <queue>
using namespace std;

queue<int> q1;
int room[20][20];
int start, aim;
int m, n;

void readData()
{
    int c, r;
    cin >> m >> n;

    for (int i(0); i < m; ++i)
    {
        for (int j(0); j < n; ++j)
        {
            cin >> room[i][j];
            if (room[i][j] == 0)
                room[i][j] = -1;
            else
                room[i][j] = -2;
        }
    }
    cin >> r >> c;
    start = r * n + c;
    cin >> r >> c;
    aim = r * n + c;
}
bool canmove(int u, int a)
{
    int row, col;
    row = u / n;
    col = u % n;
    //a: 0 up; 1 down; 2 left; 3 right;
    switch(a)
    {
        case 0: row -= 1;break;
        case 1: row += 1;break;
        case 2: col -= 1;break;
        case 3: col += 1;break;
        default: break;
    }
    if (row >= 0 && row < n && col >= 0 && col < n)
        if (room[row][col] != -2)
            return true;
    return false;
}

int moveto(int u, int a)
{
    //a: 0 up; 1 down; 2 left; 3 right;
    switch(a)
    {
        case 0: u -= n;break;
        case 1: u += n;break;
        case 2: u -= 1;break;
        case 3: u += 1;break;
        default: break;
    }

    return u;
}
int run()
{
    int u, v;
    while(!q1.empty())
    {
        u = q1.front();
        q1.pop();

        for (int i(0); i < 4; ++i)
        {
            if (canmove(u, i))
            {
                v = moveto(u, i);

                if (v == aim)
                    return room[u / n][u % n] + 1;
                else if (room[v / n][v % n] == -1)
                {
                    q1.push(v);
                    room[v / n][v % n] = room[u / n][u % n] + 1;
                }
            }
        }
    }
    return 0;
}
int main()
{
    readData();

    // initdata
    q1.push(start);
    room[start / n][ start % n] = 0;

    cout << run() << endl;

    return 0;
}
    原文作者:分支限界法
    原文地址: https://blog.csdn.net/lmj_like_c/article/details/70284246
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞