SDNU 1086 思路及实现

传送门:SDNUOJ 1086

整体思路

从起点开始依次寻找路径,如果走到头之后还没能抵达迷宫右下角,那么就去寻找别的路径

实现

首先定义变量

const int N=10;
const int n=5;
int mp[N][N];//输入的迷宫地图
bool vis[N][N];//注明某点有没有走过
typedef pair<int,int>PII;
PII path[N][N];//标记路径
struct node{
	int x,y;
}no[N*N];//下面用到
const int dx[4]={-1,0,0,1};//x轴移动
const int dy[4]={0,-1,1,0};//y轴移动
//上面这两行需要组合起来看

然后是遍历的问题

怎么知道哪条路走到(4,4)了呢?最好的方法就是发现某条路可以走到(4,4)的时候,结束遍历

所以这样就需要我们定义一个能存储实时路径的东西,也就是上面的path[][]

我们需要从(0,0)开始,所以遍历初始的时候就需要把它记作初始位置,然后标记它已经被走过了

接下来就是往它的上下左右去找路了;但是马上就能发现,在一开始就已经有两条路径出界了(往左和往上),所以我们先需要一个函数来判断有没有出界

bool judge(int x,int y)
//出界返回false,未出界返回true
{
	if(x<0||x>=n||y<0||y>=n) return false;
	return true;
}

现在有了不出界的保证了,又要面临一个问题,那就是迷宫的墙

(但是这都不算问题)只需要判断这个点是0还是1就可以了,是1就不走

现在不会卡出地图了,也不会撞墙了,但是总不能走着走着突然原路返回了吧

所以每走过一个点都要标记一下,走之前先看看要去的点有没有走过

这样就不会一段路走好几遍了

现在程序已经知道怎么样正确走迷宫了,接下来要做的就是让他去走,并且记录下他实时的路径

下面是遍历的函数

void bfs()
{
	node fir;
	fir.x=0,fir.y=0;//记定初始位置
	queue<node>q;//用队列来代表位置
	q.push(fir);//初位置进队
	vis[0][0]=true;//标记初始位置已走过
	while(!q.empty())
	{
		node t=q.front();
        //记录现位置

		q.pop();
        //队首元素出队

		if(t.x==n-1&&t.y==n-1)
		{
			return ;
            //走到头了就结束
		}
		for(int i=0;i<4;i++)
        //遍历上下左右四个方向
		{
			int tx=t.x+dx[i];
			int ty=t.y+dy[i];
			if(judge(tx,ty)&&!vis[tx][ty]&&mp[tx][ty]==0)
			//如果这个点:未出界、未走过、不是墙
			{
				vis[tx][ty]=true;
                //标定这个点已走过

				node tmp;
                //记录这个点

				tmp.x=tx,tmp.y=ty;
                //现位置定为下个循环的初始位置

				path[tx][ty]={t.x,t.y};
                //标定现位置能由上个位置到达

				q.push(tmp);
                //现位置进队
			}
		}
	}
}

然后就是如何输出了;

需要注意的是,上面的path[][]可以看成一个映射,原像是路径上的某点,像是该点在这条路径上的前一个位置,所以应该从最后一个点(4,4)开始

因而用到嵌套,从(4,4)沿着路径找回(0,0)然后再按路径行走顺序输出

下面是输出函数

void print(int x,int y)
{
	if(!x&&!y)
    //如果已经走回起点
	{
		cout<<"(0,0)"<<endl;
		return ;//跳出函数
	}
	int tx=path[x][y].first;
	int ty=path[x][y].second;
	print(tx,ty);
    //从终点沿着路径往回走
	cout<<"("<<x<<","<<y<<")"<<endl;
}

然后就可以写出整个程序了

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N=10;
const int n=5;
int mp[N][N];
bool vis[N][N];
typedef pair<int,int>PII;
PII path[N][N];
struct node{
	int x,y;
}no[N*N];
bool judge(int x,int y)
{
	if(x<0||x>=n||y<0||y>=n) return false;
	return true;
}
const int dx[4]={-1,0,0,1};
const int dy[4]={0,-1,1,0};
void print(int x,int y)
{
	if(!x&&!y)
	{
		cout<<"(0,0)"<<endl;
		return ;
	}
	int tx=path[x][y].first;
	int ty=path[x][y].second;
	print(tx,ty);
	cout<<"("<<x<<","<<y<<")"<<endl;
}
void bfs()
{
	node fir;
	fir.x=0,fir.y=0;
	queue<node>q;
	q.push(fir);
	vis[0][0]=true;
	while(!q.empty())
	{
		node t=q.front();
		q.pop();
		if(t.x==n-1&&t.y==n-1)
		{
			return ;
		}
		for(int i=0;i<4;i++)
		{
			int tx=t.x+dx[i];
			int ty=t.y+dy[i];
			if(judge(tx,ty)&&!vis[tx][ty]&&mp[tx][ty]==0)
			{
				vis[tx][ty]=true;
				node tmp;
				tmp.x=tx,tmp.y=ty;
				path[tx][ty]={t.x,t.y};
				q.push(tmp);
			}
		}
	}
}
int main()
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			cin>>mp[i][j];
		}
	}
	bfs();
	print(4,4);
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值