打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
华为机试HJ43:迷宫问题

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

题目描述:

定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一格是可以走的路。

本题含有多组数据。

输入描述:

输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

输出描述:

左上角到右下角的最短路径,格式如样例所示。

示例:

输入:

5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出:

(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)

解题思路:

回溯法解迷宫问题,构建结构体list存放x和y,以及next指针存储路径;push函数即前进,让路径加入新位置,pop函数即后退,将路径弹出一个位置,chkExit函数判断是否到达终点。

利用两维数组a存放迷宫图,设置(0,0)为起点开始出发,path为路径,因为迷宫没有围墙,所以要判断边界,前进则通过分析上下左右是否有可行路径决定,如果走到某个点没有可行路径了,就后退,直到到达某个点有另一条分支可行,注意该过程path一直放入弹出位置信息,确保存放的位置是最终到达终点的路径;因为path存放顺序倒序,我将其整理成string格式放入vector中,再逆序输出vector,完成路径输出。

测试代码:

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

// 构建结构体
struct list
{
int x, y;
struct list *next;
};
typedef struct list node;
typedef node* link;
link push(link path, int x, int y);
link pop(link path, int *x, int *y);
int chkExit(int x, int y, int ex, int ey);
// 路径加入新点
link push(link path, int x, int y)
{
link newnode;
newnode = new node;
if (!newnode)
{
cout << "Error:内存分配失败!" << endl;
return NULL;
}
newnode->x = x;
newnode->y = y;
newnode->next = path;
path = newnode;
return path;
}
// 路径弹出不通的点
link pop(link path, int *x, int *y)
{
link top;
if (path != NULL)
{
        link temp=path;
path = path->next;
*x = path->x;
*y = path->y;
        delete temp;
return path;
}

return path;
}
// 到达终点
int chkExit(int x, int y, int ex, int ey)  
{
if ((x == ex) && (y == ey))
{
return 1;
}
return 0;
}

int main()
{
    int row,col;
    while(cin>>row>>col)
    {
        int**a=new int *[row];
        for(int i=0;i<row;++i)
        {
            a[i]=new int[col];
        }
        for(int i=0;i<row;i++)
        {
            for(int j=0;j<col;j++)
            {
                cin>>a[i][j];
            }
        }
        link path = NULL;
        int x=0,y=0;
        path=push(path,x,y);
        while (x<row &&y<col)
        {
            a[x][y]=2;
            // 往上走
            if(x-1>=0)
            {
                if(a[x-1][y]==0)
                {
                    x-=1;
                    path=push(path,x,y);
                    continue;
                }
            }
            // 往下走
            if(x+1<row)
            {
                if(a[x+1][y]==0)
                {
                    x+=1;
                    path=push(path,x,y);
                    continue;
                }
            }
            // 往左走
            if(y-1>=0)
            {
                if(a[x][y-1]==0)
                {
                    y-=1;
                    path=push(path,x,y);
                    continue;
                }
            }
            // 往右走
            if(y+1<col)
            {
                if(a[x][y+1]==0)
                {
                    y+=1;
                    path=push(path,x,y);
                    continue;
                }
            }
            // 判断是否到达终点
            if(chkExit(x, y, row-1, col-1) == 1)
            {
                break;
            }
            // 倒退
            path=pop(path,&x,&y);
        }
        vector<string> result;
        while(path!=NULL)
        {
            string p="("+to_string (path->x)+","+to_string (path->y)+")";
            result.push_back(p);
            path=path->next;
        }
        for(int i=result.size()-1;i>=0;--i)
        {
            cout<<result[i]<<endl;
        }
    }

    return 0;
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
c 迷宫
每日一题 C++版(走迷宫)
追根溯源——回溯算法
066.图的广度优先遍利
excel中如何用vba打开一个相对路径下的资料?
利用栈实现迷宫的求解
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服