利比亚行动(广搜,迷宫问题)

2011年3月16日以来,利比亚爆发的骚乱不断升级,已严重危及到普通民众和各国在利比亚工作的人员的安全。为了尽快救出在利比亚的同胞,根据利比亚的形势,我国政府告诉每个在利比亚的公民,如何行动才能最快地到达安全的地方,然后由我国派出的飞机、轮船、汽车接回国。 假设利比亚的地图可以描述为一个n行m列的长方形,待拯救的同胞小A在1行1列处,安全的目标位置在n行m列处。小A每次只能向相邻的上、下、左、右四个方向移动,即如果小A现在的位置是i行j列,小A的下一步位置将到达i-1行j列、i+1行j列、i行j-1列、i行j+1列这四个位置之一,当然小A不能移出n行m列的长方形。 利比亚是一个多沙漠且地形复杂的国家,某些位置是很危险的,人不能去。 给出利比亚的地图,请告诉小A从起点(1,1)走到终点(n,m)最快需要多少步呢?

输入格式:

第一行有2个正整数n,m (1≤n≤2000,1≤m≤2000),它们之间以一个空格分隔,表示利比亚的地形可以分为n行m列。 接下来n行,每行m个字符,分别表示地图中该位置的信息。其中: 字符“*”表示这个位置是建筑物、河流、有地雷等人无法走到的位置(保证起点终点不是“*”); 小数点“.”表示人可以走到该位置。

输出格式:

只有一行,该行只有一个正整数。表示为小A从起点到终点,最快需要多少步。

输入样例:

3 5
.*...
...*.
*..*.

输出样例:

8

以前写迷宫类题目经常要调试各种BUG,而且每次用的方法也有点差异,并不统一,经常做着做着,发现用这种方法会出现一些比较麻烦的地方。,似乎是因为之前没想一下代码构成,直接开始做,导致了各种头痛(怕了),这一次几乎直接无错,一次通过,而且效率和代码也较为理想,因此保存此代码作为迷宫类模版

思路,

1.首先是构建一个坐标结构体,内有该坐标的x,y点和到达该坐标的步数,以及构造函数,为了后面的赋值方便。

2.写广度搜索框架,包括定义标记已访问数组,横纵偏移量数组

3.写check函数检查一个坐标点是否能够加入队列内(检查其是否越界,是否为障碍物,以及是否访问过了)

#include<iostream>
#include<queue>
using namespace std;
struct pos {
	int x,y,cunt;
	pos(int a,int b,int c) {   //构造函数
		x=a;
		y=b;
		cunt=c;
	}
};
char a[2002][2002];
int n,m,z[4]= {0,0,1,-1},h[4]= {1,-1,0,0};
bool flag[2002][2002]= {false};
bool check(int x,int y) { //检查其是否越界,是否为障碍物,以及是否访问过了
	if(x>=0&&x<n&&y>=0&&y<m) {
		if(flag[x][y]==false) {
			if(a[x][y]=='.')return true;
		}
	}
	return false;
}
int bfs() {
	queue<pos> q;
	q.push(pos(0,0,0));
	flag[0][0]=true;
	while(!q.empty()) {
		pos top =q.front();
		q.pop();
		if((top.x==n-1)&&(top.y)==m-1)return top.cunt;
		for(int i=0; i<4; i++) {
			int x=top.x+z[i];
			int y=top.y+h[i];
			int cunt=top.cunt+1; //定义局部变量x,y,cunt,优于宏定义,可以增加运行速度
			if(check(x,y)) {     //因为x,y需要用到多次
				q.push(pos(x,y,cunt));
				flag[x][y]=true;
			}
		}
	}
	return -1; //无法到达终点
}
int main() {
	cin>>n>>m;
	for(int i=0; i<n; i++)cin>>a[i];
	cout<<bfs();
	return 0;
}
发布了42 篇原创文章 · 获赞 16 · 访问量 3409

猜你喜欢

转载自blog.csdn.net/qq_41542638/article/details/96346900
今日推荐