BFS的应用-走迷宫

//算法竞赛入门经典(刘汝佳) - BFS的应用,走迷宫

# include <stdio.h>
# include <string.h>
const int MAXN = 100+10;
int q[MAXN*MAXN];
//走迷宫
int vis[MAXN][MAXN];
int fa[MAXN][MAXN];
int dist[MAXN][MAXN];
int maze[MAXN][MAXN]; 
int last_dir[MAXN][MAXN]; 
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0}; 
int n,m;//m表示一行有多少元素 
char name[4]={'R','L','D','U'}; 
void bfs(int x,int y){
	
	//初始化 
	int front=0,rear=0,d,u;
	u=x*m+y;      
	vis[x][y] = 1;  //标记已经访问过。
	fa[x][y] = u;   //起点的根节点设置为u,循环输出路径的结束条件
	dist[x][y] = 0; //路径长度初始为0.
	q[rear++] = u;  //起点入队列。
	while(front < rear){
		u=q[front++];
		//得到当前节点。 
		x=u/m; y=u%m;
		for(d = 0; d < 4; d++){//分别往四个方向走 
			int nx=x+dx[d],ny=y+dy[d];
			if(nx>=0 && nx<n && ny>=0 && ny<m 
				&& maze[nx][ny] && !vis[nx][ny]){//maze表示如果单元格是空地
				int v=nx*m+ny;
				q[rear++]=v;
				vis[nx][ny]=1;
				fa[nx][ny]=u;  //静态链表记录祖先结点,右边是祖先。
				dist[nx][ny] = dist[x][y] + 1;//到nx,ny的距离等于到x,y的距离加1.
				last_dir[nx][ny] = d;//保存从父节点移动到此的方向。 
			}
		} 	 
	} 		
} 

//打印路径,递归形式 
void print_path(int x,int y){
	int fx = fa[x][y]/m;
	int fy = fa[x][y]%m;
	if(fx!=x || fy!=y){
		print_path(fx,fy);
		putchar(name[last_dir[x][y]]);
	}
} 

//打印路径,非递归形式
int dir[MAXN*MAXN];
void print_path2(int x,int y){
	int c=0;
	for(;;){
		int fx=fa[x][y]/m;
		int fy=fa[x][y]%m;
		if(fx==x && fy==y)
			break;
		dir[c++]=last_dir[x][y];
		x=fx;
		y=fy;
	}
	while(c--){
		putchar(name[dir[c]]);
	}
} 
int main() {
	
	//输入几行几列
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			maze[i][j]=1;
		}
	}
	
	memset(vis,0,sizeof(vis));
	memset(fa,0,sizeof(fa));
	memset(dist,0,sizeof(dist));	
	memset(last_dir,0,sizeof(last_dir));

	int total,xx,yy;
	scanf("%d",&total); 
	for(int j=0;j<total;j++){//将墙壁初始化为0
		scanf("%d %d",&xx,&yy);
		maze[xx][yy]=0;
	}
	bfs(0,1);
	print_path2(3,4);
	return 0;
 }
<p><span style="color:#4472C4;">/*</span><span style="color:#4472C4;">测试数据</span></p><p><span style="color:#4472C4;">6 5</span></p><p><span style="color:#4472C4;">7</span></p><p><span style="color:#4472C4;">0 2</span></p><p><span style="color:#4472C4;">1 1</span></p><p><span style="color:#4472C4;">2 1</span></p><p><span style="color:#4472C4;">3 1</span></p><p><span style="color:#4472C4;">2 3</span></p><p><span style="color:#4472C4;">2 4</span></p><p><span style="color:#4472C4;">4 3</span></p><span style="color:#4472C4;">*/</span> 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随风浪仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值