01迷宫的总结

本文介绍了如何使用广度优先搜索(BFS)解决01迷宫问题。关键思路是记录每次不同的搜索路径,并在遇到已探索节点时,查找之前的搜索结果。如果节点未被探索,则进行新的搜索。文中给出了相应的代码实现。

首先,大家先看一下题吧:01迷宫
大体的思路:广搜。
细节:首先,我要把每次广搜的结果储存起来,然后每一次不一样的广搜(是之前从来没有遍历过的)全部储存为这一次遍历的编号。如果询问的点是以前广搜过的,那么就输出那一次广搜的结果。如果没有遍历过,那么就进行一次广搜。
代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iomanip>
#include <string>
#include <math.h>
#include <cmath>
#include <time.h>
#include <cmath>
#include <stack>
#include <queue>
//#include<windows.h>
//#include <bits/stdc++.h>
using namespace std;
/*
输入:

输出:


*/
int cnt;//每一次广搜的计数器 
int n,m;//n行,n列,m个询问
char a[1001][1001];//初始地图 
int sx,sy;//起始坐标(因为每一次都不一样) 
int k=1;//当前遍历的编号 
int g[1000010];
struct node {//队列 
	int x,y;//坐标 
} edge[1000010];
int head=1,tail=1;//队头,队尾 
int nxt[5][2]= {{-1,0},{1,0},{0,-1},{0,1}};//方向 
int book[1001][1001];
void bfs() {
	edge[tail].x=sx;//初始化 
	edge[tail].y=sy;
	book[sx][sy]=k;
	cnt=1;
	tail++;//队尾+1 
	while(head<tail) {//如果队里不为空 
		for(int i=0; i<4; i++) {//遍历每一个方向 
			int nx=edge[head].x+nxt[i][0];//临时的方向 
			int ny=edge[head].y+nxt[i][1];
//			cout << a[edge[head].x][edge[head].y] << " " << a[nx][ny] << " " << nx << " "<< ny << endl;
			if(nx>0&&ny>0&&nx<=n&&ny<=n&&book[nx][ny]==0&&//如果没有超出边界 
			        ((a[edge[head].x][edge[head].y]=='1'&&a[nx][ny]=='0')//如果是从1走向0
			         ||(a[edge[head].x][edge[head].y]=='0'&&a[nx][ny]=='1'))) {//如果是从0走向1 
//				cout << book[nx][ny] <<" ";
//				cout << book[1][1] << " ";
				book[nx][ny]=k;//赋值为本次遍历编号 
//				cout << nx <<" " << ny << "!!!" <<endl;
				edge[tail].x=nx;//
				edge[tail].y=ny;
				cnt++;//计数器+1 
//				cout << edge[tail].cnt << endl;
//				cout << tail << endl;
				tail++;//为下一个元素进行准备 
			}
		}
		head++;//弹出队头元素 
	}
}
int main() {
//freopen("**.in","r",stdin);
//freopen("**.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) {//初始地图 
		for(int j=1; j<=n; j++) {
			cin >> a[i][j];
		}
	}
	while(m--) {//遍历m次 
		cin >> sx >> sy;//初始坐标 
		cnt=1;//初始化 
		tail=1;
		head=1;
//		for(int i=0;i<=n;i++){
//			for(int j=0;j<=n;j++){
//				book[i][j]=0;
//			}
//		}
		if(book[sx][sy]!=0) {//如果已经广搜过 
			cout << g[book[sx][sy]] << endl;//直接输出 
		} else {
			bfs();//负责进行广搜 
			g[k]=cnt;//把这次广搜的结果储存起来 
			k++;//编号加一 
			cout << cnt << endl;
		}
	}

//fclose(stdin);
//fclose(stdout);
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值