华为机试HJ43:迷宫问题

Posted 翟天保Steven

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华为机试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;
}

以上是关于华为机试HJ43:迷宫问题的主要内容,如果未能解决你的问题,请参考以下文章

华为机试HJ89:24点运算

华为机试HJ89:24点运算

华为机试HJ50:四则运算

华为机试HJ82:将真分数分解为埃及分数

华为机试HJ17:坐标移动

华为机试HJ54:表达式求值