BFS记录方案

1076. 迷宫问题 - AcWing题库

给定一个 n×n 的二维数组,如下所示:

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表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

数据保证至少存在一条从左上角走到右下角的路径。

输入格式

第一行包含整数 n。

接下来 n行,每行包含 n 个整数 0 或 1,表示迷宫。

输出格式

输出从左上角到右下角的最短路线,如果答案不唯一,输出任意一条路径均可。

按顺序,每行输出一个路径中经过的单元格的坐标,左上角坐标为 (0,0),右下角坐标为 (n−1,n−1)

数据范围

0≤n≤1000

输入样例:

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

输出样例:

0 0
1 0
2 0
2 1
2 2
2 3
2 4
3 4
4 4


记录方法1:从终点开始bfs,维护一个该点是由谁扩展来的,从起点逐个输出就行了 PII pre[N][N];

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
typedef pair<int,int>PII;
int n;
int g[N][N];
int dist[N][N];
PII q[N*N];
PII pre[N][N];
int dx[]={-1,1,0,0};
int dy[]={0,0,1,-1};
void bfs(int x,int y)
{
	int tt=-1,hh=0;
	
	q[++tt]={x,y};
	memset(dist,-1,sizeof dist);
	dist[x][y]=0;
	while(hh<=tt)
	{
		auto t=q[hh++];
		int x1=t.first,y1=t.second;
		for(int i=0;i<4;i++)
		{
			int temx1=x1+dx[i],temy1=y1+dy[i];
			if(temx1<0||temx1>=n||temy1<0||temy1>=n)continue;
			if(dist[temx1][temy1]!=-1||g[temx1][temy1])continue;
			dist[temx1][temy1]=dist[x1][y1]+1;
			pre[temx1][temy1]={x1,y1};
			q[++tt]={temx1,temy1};
		}
	}
	
	
}
void dfs(int x,int y)
{
	if(x==0&&y==0)
	{
		printf("0 0\n");
		return;
	}
	
	dfs(pre[x][y].first,pre[x][y].second);
	
	cout<<x<<" "<<y<<endl;
}


int main()
{
	cin>>n;
    for(int i=0;i<n;i++)
     for(int j=0;j<n;j++)
      cin>>g[i][j];
      
    bfs(n-1,n-1);
    
    PII ed={0,0};
    while(1)
    {
    	printf("%d %d\n",ed.first,ed.second);
    	if(ed.first==n-1&&ed.second==n-1)break;
    	ed=pre[ed.first][ed.second];
    }
 	
}





记录方法2:从源点bfs,维护pre    dfs输出就行
 

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
typedef pair<int,int>PII;
int n;
int g[N][N];
int dist[N][N];
PII q[N*N];
PII pre[N][N];
int dx[]={-1,1,0,0};
int dy[]={0,0,1,-1};
void bfs(int x,int y)
{
	int tt=-1,hh=0;
	
	q[++tt]={x,y};
	memset(dist,-1,sizeof dist);
	dist[x][y]=0;
	while(hh<=tt)
	{
		auto t=q[hh++];
		int x1=t.first,y1=t.second;
		for(int i=0;i<4;i++)
		{
			int temx1=x1+dx[i],temy1=y1+dy[i];
			if(temx1<0||temx1>=n||temy1<0||temy1>=n)continue;
			if(dist[temx1][temy1]!=-1||g[temx1][temy1])continue;
			dist[temx1][temy1]=dist[x1][y1]+1;
			pre[temx1][temy1]={x1,y1};
			q[++tt]={temx1,temy1};
		}
	}
	
	
}
void dfs(int x,int y)
{
	if(x==0&&y==0)
	{
		printf("0 0\n");
		return;
	}
	
	dfs(pre[x][y].first,pre[x][y].second);
	
	cout<<x<<" "<<y<<endl;
}


int main()
{
	cin>>n;
    for(int i=0;i<n;i++)
     for(int j=0;j<n;j++)
      cin>>g[i][j];
      
    bfs(0,0);
    
    // PII ed={0,0};
    // while(1)
    // {
    	// printf("%d %d\n",ed.first,ed.second);
    	// if(ed.first==n-1&&ed.second==n-1)break;
    	// ed=pre[ed.first][ed.second];
    // }
  //  printf("%d %d",pre[n-1][n-1].first,pre[n-1][n-1].second);
    dfs(n-1,n-1);	
}










 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值