sdnuoj1086

链接1086

题意

定义一个二维数组:

int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走

的路,只能横着走或竖着走,不能斜着走,要求编

程序找出从左上角到右下角的最短路线。

Input

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

Output

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

Sample Input

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output

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

这个题是最短路的类型题中的需要输出最短路的坐标的题
找最短路时的思路和平常的最短路的题差不多,但是不同的是你需要输出这个最短路
因为bfs是广搜,你最终会把每个节点都塞进去,然后pop出来,所以想在找到最短路的时候直接输出最短路是很难实现的,因为你根本不知道哪个点的下一个节点用得到,就不知道这个点是不是你要的点,而这个时候我们可以用回溯,就是从最后一个点,找上一个点,就需要我们记录一个节点时要同时记录下一个节点,方便回溯
还有一点就是,因为我们如果从起点开始搜,那输出的时候就是从终点开始回溯,那就相当于是倒序输出,你可以在找个数存一下,再正序输出,你还可以一开始就从终点往起点查找,这样最后就是从起点回溯,相当于正序输出,很方便

代码如下

#include<bits/stdc++.h>
using namespace std;

struct ranran
{
    
    
    int x, y;
};
ranran tr[6][6];//这个结构体的二维数组很重要,像你一样重要
/*
定义一个ranran的结构体的二维数组tr
从最后的终点往起点搜索,这样方便正序输出
而就是通过这个结构体的二维数组实现的
tr[][]里面的[]是从终点开始往起点搜的下一个节点的坐标
而tr[][].x / y是现在的点的坐标
我们最后通过的是从起点开始输出,拥有的是tr[][]中两个[]的数
通过这两个数索引会他的上一个的点的坐标
就是tr[][].x / y
输出的是这个x, y

*/

int vis[6][6] = {
    
    0};//用来判断有没有走过这个点
int tang[6][6];//存地图
int dx[] = {
    
    1, 0, 0, -1};//上下左右走
int dy[] = {
    
    0, 1, -1, 0};
int judge(int x, int y)//判断这点能不能走
{
    
    
    if (vis[x][y] == 0 && tang[x][y] == 0 && x <= 4
        && y <= 4 && x >= 0 && y >= 0)
    {
    
    
        return 1;
    }
    return 0;
}

void bfs()
{
    
    
    ranran now, next;
    now.x = 4;//从终点开始搜,所以肯定得把终点的坐标塞进去
    now.y = 4;
    queue<ranran>q;
    //vis[now.x][now.y] = 1;//标记一下终点
    q.push(now);
    while(!q.empty())//当队列不为空的时候就进入循环
    {
    
    
        now = q.front();//取栈首
        q.pop();//给他扔出去
        if(now.x == 0 && now.y == 0)//判断是不是搜到了起点
        {
    
    
            break;
        }
        int tx, ty;//临时变量 用来存下一个的点的坐标,

        for(int i = 0; i < 4; i++)//上下左右走
        {
    
    
            tx = now.x + dx[i];
            ty = now.y + dy[i];
            if(judge(tx, ty))
            {
    
    
                next.x = tx;
                next.y = ty;
                tr[next.x][next.y].x = now.x;//当按序输出的时候,这个now就相当于next
                tr[next.x][next.y].y = now.y;
                q.push(next);//塞进去
                vis[next.x][next.y] = 1;
            }
        }
    }

}
void printf()
{
    
    
    int x = 0;
    int y = 0;// 起点为(0, 0);
    while(!(x == 4 && y == 4))
    {
    
    
        printf("(%d, %d)\n", x, y);
        int rx, ry;
        rx = tr[x][y].x;//用rx, ry 来存一下下一个点的坐标 如果直接用x = tr[][].x 那么给y赋值的时候这个x就被改变了,所以得用其他变量存一下
        ry = tr[x][y].y;
        x = rx;
        y = ry;
    }
    printf("(%d, %d)\n", x, y);//得输出(4, 4)
}
int main()
{
    
    
    //memset(vis, 0, sizeof(vis));
    for(int i = 0; i < 5; i++)
    {
    
    
        for(int j = 0; j < 5; j++)
        {
    
    
            cin>>tang[i][j];
        }
    }
    bfs();
    printf();
    return 0;
}
/*
0 0 0 0 1
1 0 1 0 1
1 0 0 1 1
1 0 0 0 0
0 0 0 0 0
*/

猜你喜欢

转载自blog.csdn.net/weixin_51216553/article/details/110506235