poj 3984

Description

定义一个二维数组:

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深度优先。将已经访问的状态用标记管理起来,可以很好的做到由近及远搜索,相当于不停的以起始节点画同心圆,并检查同心圆上有没有终点。

这道题还要求输出最短路径,因此还需要一个队列记录每一个路径节点的前继节点,然后利用栈进行逆序输出。

遇到的问题:

1.逆序输出所有前继节点。首先要将其压入栈中,判断条件写为

 while(!(pairr.first==0&& pairr.second==0))是正确的,之前写的是 while(pairr.first!=0&& pairr.second!=0)

明显的逻辑错误

2.输出的格式一定要和题目相当,坐标逗号之后要添加一个空格,否则就会出现 Presentation Error

最后AC的代码

#include <iostream>  
#include <queue>  
#include <stack>  
#include <cstdio>  
  
using namespace std;  
  
typedef pair<int,int> P;//pair表示状态  
//typedef node{  
//    int x,y;  
//};//设置节点记录走过的路径  
//node pre[10][10];  
P pre[100][100];  
const int INF=1000000;  
int mp[5][5];//迷宫字符数组  
int shortest[5][5];//起点到各个位置的最小距离  
  
int dx[4]={1,0,-1,0}, dy[4]={0,1,0,-1};//上下左右四个方向移动dx  
  
  
void bfs()  
{  
    //初始化最小距离的数组  
    for(int i=0; i<5; i++)  
    {  
        for(int j=0; j<5;j++)  
        {  
            shortest[i][j]=INF;  
        }  
    }  
    //初始化队列,将起点压入队列  
    queue<P> que;  
    que.push(P(0,0));  
    shortest[0][0]=0;//起点到起点的距离为0  
  
    while(que.size())//队列不为空  
    {  
        P pairs = que.front();  
        que.pop();  
        if(pairs.first==4 && pairs.second==4)//如果队列顶端是终点,则结束  
            break;  
        //不是终点  
        for(int i=0;i<4;i++)  
        {  
            int nx = pairs.first + dx[i];  
            int ny = pairs.second + dy[i];  
            //在迷宫内,且当前位置可走,且没有访问过  
            if(nx>=0 && nx<=4 && ny>=0 && ny<=4 && mp[nx][ny]==0 && shortest[nx][ny]== INF)  
            {  
                que.push(P(nx,ny));//添加到队列中  
                shortest[nx][ny]=shortest[pairs.first][pairs.second]+1;//更新最短路径  
                pre[nx][ny]=pairs;//记录前继节点  
                //cout<<"test"<<pre[nx][ny].first<<pre[nx][ny].second;  
  
            }  
  
        }  
    }  
  
}  
void print(P pairr)  
{  
  
    stack<P> way;  
    int test=0;  
    //cout<<pre[2][1].first<<pre[2][1].second<<endl;  
    while(!(pairr.first==0&& pairr.second==0)){  
        way.push(pairr);  
        //cout<<"test"<<pre[pairr.first][pairr.second].first<<pre[pairr.first][pairr.second].second<<endl;  
        pairr=pre[pairr.first][pairr.second];  
        test++;  
        //cout <<"times"<<test<<endl;  
    }  
  
    printf("(0, 0)\n");  
    while(way.size())  
    {  
        P now=way.top();  
        way.pop();  
        printf("(%d, %d)\n",now.first,now.second);  
    }  
  
return;  
}  
  
int main()  
{  
    for(int i=0;i<5;i++)  
        for(int j=0;j<5;j++)  
            scanf("%d",&mp[i][j]);  
    bfs();  
    P ed;  
    ed.first=ed.second=4;  
    //cout<<ed.first<<ed.second;  
    print(ed);  
    return 0;  
}  

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值