华为机试HJ43:迷宫问题

简介: 华为机试HJ43:迷宫问题

题目描述:

定义一个二维数组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;
}


相关文章
华为机试HJ107:求解立方根
华为机试HJ107:求解立方根
151 1
|
算法
华为机试HJ108:求最小公倍数
华为机试HJ108:求最小公倍数
110 1
|
Serverless 测试技术
华为机试HJ97:记负均正
华为机试HJ97:记负均正
135 1
华为机试HJ105:记负均正II
华为机试HJ105:记负均正II
121 1
华为机试HJ103:Redraiment的走法
华为机试HJ103:Redraiment的走法
191 2
华为机试HJ88:扑克牌大小
华为机试HJ88:扑克牌大小
116 0
|
机器学习/深度学习
华为机试HJ35:蛇形矩阵
华为机试HJ35:蛇形矩阵
|
机器学习/深度学习
华为机试HJ53:杨辉三角的变形
华为机试HJ53:杨辉三角的变形
|
测试技术
华为机试HJ85:最长回文子串
华为机试HJ85:最长回文子串