题意:
有一张地图,地图中,左上角为入口,右下角为出口。地图中,1表示不可以走,0表示可以走。保证入口,出口为0。编写程序找到入口到出口的最短路线。
输入:
输入是一个5 × 5的二维数组,仅由0、1两数字组成,表示法阵地图。
Sample Input:
0 1 0 0 0
0 1 0 1 0
0 1 0 1 0
0 0 0 1 0
0 1 0 1 0
输出:
输出若干行,表示从左上角到右下角的最短路径依次经过的坐标。数据保证有唯一解。
Sample Output:
(0, 0)
(1, 0)
(2, 0)
(3, 0)
(3, 1)
(3, 2)
(2, 2)
(1, 2)
(0, 2)
(0, 3)
(0, 4)
(1, 4)
(2, 4)
(3, 4)
(4, 4)
思路:
将地图初始化为5*5的数组,用1表示地图中的障碍,用0表示地图可到达但还未到达的地方。从起点开始进行广度优先搜索(BFS),因为数字0,1已经被使用,因此使用>2的数字对路径长度进行标记(即将起点标记为2,起点周围可到达的点标记为3,以此类推),遇到出口搜索停止。最后从出口按标记记录路径(每次寻找比当前点路径长度小一的点进行记录)直到回到起点,则最短路径找到。
代码:
#include <iostream>
#include<stdio.h>
#include<queue>
#include<vector>
using namespace std;
const int maxn=5;
int vis[maxn][maxn];
int dx[]={1,-1,0,0},
dy[]={0,0,1,-1};
int sx=0,sy=0,tx=4,ty=4;
struct Point{
int x;
int y;
Point(int thex,int they)
{
x=thex,y=they;
}
};
queue<Point> q;
void bfs()
{
q.push(Point(sx,sy));
vis[sx][sy]=2;
while(!q.empty())
{
Point now=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int x=now.x+dx[i];
int y=now.y+dy[i];
if(x>=0&&x<maxn&&y>=0&&y<maxn&&vis[x][y]==0)
{
vis[x][y]=vis[now.x][now.y]+1;
q.push(Point(x,y));
if(x==tx&&y==ty)
return;
}
}
}
}
void print()
{
vector<Point> v;
Point now(tx,ty);
v.push_back(Point(tx,ty));
while(true)
{
if(now.x==sx&&now.y==sy)
{
//printf("(%d,%d)\n",sx,sy);
break;
}
for(int i=0;i<4;i++)
{
int x=now.x+dx[i],y=now.y+dy[i];
if(x>=0&&x<maxn&&y>=0&&y<maxn&&vis[x][y]==vis[now.x][now.y]-1)
{
v.push_back(Point(x,y));
now.x=x,now.y=y;
break;
}
}
}
vector<Point>::reverse_iterator it=v.rbegin();
printf("(%d, %d)",it->x,it->y);
it++;
for(;it!=v.rend();it++)
printf("\n(%d, %d)",it->x,it->y);
}
int main(int argc, char** argv) {
for(int i=0;i<maxn;i++)
for(int j=0;j<maxn;j++)
cin>>vis[i][j];
bfs();
print();
return 0;
}