嘿嘿,如果这道题是求最短的步数,那么用BFS算法就可以了。但是因为还要输出路径,可能还要保存每个结点的上一个结点的坐标,最后再用递归或是迭代的方法逆序输出坐标,博主昨天学会了bfs算法表示真的很高兴,慢慢向前进吧。
具体思路如下
可以申请几个数组来存储坐标,以及标志已访问的结点,还有上一个节点的坐标;
不过博主用的是一个结构体二维的数组,结构体定义了该节点自己的位置,以及该节点上一个结点的坐标,还有该结点的值(0代表路,1代表墙);
每个位置的下一步都可能有四个位置,向上一步,向下一步。向左一步,向右一步。
从入口遍历每个位置,若该位置不为出口,则将该位置上一个位置的坐标记下(入口的上个位置坐标初始化为零)
将其压入队列中,同时继续遍历上一个位置的另一个分支节点位置;
若该结点位置即为出口坐标,那么调用输出函数利用递归或则迭代逆序输出(博主用的是递归哈,如果用迭代的话栈个人觉得比较方便,嘿嘿);
这道题的时间复杂性应该是O(n*n)(n是维数)
最后比较坑的事输出坐标时格式是(x, y),中间有个空格,还有就是一定要初始化,这道题AC让博主高兴了好久
代码有点长有点乱哈,如果有什么不懂的可以留言我会尽我所能高数你我的想法哈,谢谢啊
#include <iostream>
#include<queue>
using namespace std;
#define n 5
int x,y;
struct poi //定义结构体可能会比用多个数组方便,但是使用起来会不太好看哈
{
int px,py;
int x,y;
int item; //该坐标的值,即是路还是墙
int vis; //标记该点是否已被访问,1代表已被访问,0代表未被访问
};
queue<poi> q; //定义一个队列
poi d[n][n]; //申请一个结构体数组
void bfs();
void print(int rx,int ry);
void print(int rx, int ry)
{
if((rx==0)&&(ry==0))
{
cout<<“(“<<rx<<“, “<<ry<<“)”<<endl;
return;
}
print(d[rx][ry].px,d[rx][ry].py); //递归调用并传递该结点的上一个结点坐标
cout<<“(“<<rx<<“, “<<ry<<“)”<<endl; //输出时记得都好后面有个空格
return;
}
void bfs()
{
poi head;
int dx,dy;
d[0][0].vis=1; //初始化
q.push(d[0][0]); //访问后弹出队列,访问下一个
while(!q.empty())
{
head=q.front();
q.pop();
for(int i=1;i<=4;i++) //四种可能,也可用存储-1,1,0,的数组操作
{
if(i==1)
{dx=head.x-1;dy=head.y;}
else if(i==2)
{dx=head.x+1;dy=head.y;}
else if(i==3)
{dy=head.y-1;dx=head.x;}
else
{dy=head.y+1;dx=head.x;}
if((dx<0)||(dy<0)||(dx>n)
||(dy>n)||(d[dx][dy].item==1)) continue; //判断是否越界即小于零或超出维数或者该点为墙无法通过
if(!d[dx][dy].vis)
{
d[dx][dy].px=head.x;
d[dx][dy].py=head.y;
d[dx][dy].vis=1;
q.push(d[dx][dy]);
}
if((dx==n-1)&&(dy==n-1))
{
print(dx,dy);
return ;
}
}
}
return;
}
int main()
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{ //初始化很重要
cin>>d[i][j].item;
d[i][j].x=i; //给每个结点赋值坐标
d[i][j].y=j;
d[i][j].vis=0;
d[i][j].px=0;
d[i][j].py=0;
}
while(!q.empty())q.pop(); //清空队列也很重要
bfs();
return 0;
}