刚看到这一道题,我个人是狂喜的。没错就是狂喜,哈哈哈。
后来才明白每一道中文题目都不是从天下掉下里的。哎,根本不会输出路径的问题,于是在网上找呀找 找到外婆桥,终于找到了一种我比较好理解的方法。就是用vis数组保持前缀进行回溯,我们平时在处理vis标记时大多用的波尔数组只存在0,1;而这次我们把他开成int类型,每次都记录上一次走的方向就可以了,那么问题来了如果这一步走的是方向数组的dir[0]这一步的话就会与标记是否走过起冲突,而再开一个数组对空间的浪费又太大,这个时候我们只需要把i+1存入vis数组就可以了,在每次回溯的时候再把1减去,那么回溯是怎么才能停止呢,它的边界条件是什么,这里采用的是让初始点的vis为-1才解决这个问题,当判断-1出现就不需要接着向下面递归了。
代码就直接贴出来了。对了问题的 链接http://poj.org/problem?id=3984;
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
int map[5][5],vis[5][5];
int dir[4][2]={1,0 ,-1,0 ,0,-1 ,0,1};
const int ex=4,ey=4;
struct point
{
int x;
int y;
};
bool check(struct point a)
{
if(a.x<0||a.x>=5||a.y<0||a.y>=5) return 0;
return 1;
}
void bfs()
{
queue<point> que;
struct point head,next;
head.x=0;head.y=0;
que.push(head);
while(!que.empty())
{
head=que.front();
que.pop();
if(head.x==ex&&head.y==ey)
{
return ;
}
for(int i=1;i<=4;i++)
{
next.x=head.x+dir[i-1][0];
next.y=head.y+dir[i-1][1];
if(check(next)&&!map[next.x][next.y]&&vis[next.x][next.y]==0)
{
vis[next.x][next.y]=i;
que.push(next);
}
}
}
}
void pr(int x,int y)
{
if(vis[x][y]!=-1)
{
int xx,yy;
xx=x-dir[vis[x][y]-1][0];
yy=y-dir[vis[x][y]-1][1];
pr(xx,yy);
}
printf("(%d, %d)\n",x,y);
}
int main()
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
scanf("%d",&map[i][j]);
}
}
memset(vis,0,sizeof(vis));
vis[0][0]=-1;
bfs();
pr(ex,ey);
return 0;
}