BFS专题6 字符迷宫

题目:

样例1:

输入
5 5
.....
.*.*.
.*S*.
.***.
...T*

输出
11

 样例2:

输入
5 5
.....
.*.*.
.*S*.
.***.
..*T*

输出
-1

思路:

        单纯的BFS迷宫问题,只是数字迷宫变成了字符迷宫。操作和 数字迷宫 一样的。

代码详解如下:

#include <iostream>
#include <queue>
#include <unordered_map>
#define endl '\n'
#define int long long
#define x first
#define y second
#define mk make_pair
#define YES puts("YES")
#define NO puts("NO")
#define umap unordered_map
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 500;

// 坐标变量
using PII = pair<int,int>;

// 控制坐标方向
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};

int n,m;
char g[N][N];
bool st[N][N];

// 判断是否可以走动该坐标
inline bool isRun(int& x,int& y)
{
	return (~x && ~y && x < n && y < m && (g[x][y] == '.' || g[x][y] == 'T') && !st[x][y]);
}

inline int BFS(PII &s,PII &e)
{
	int step = 0;
	// 存储坐标
	queue<PII>q;
	// 存储起点
	q.push(s);
	while(q.size())
	{
		int sz = q.size();
		while(sz--)
		{
			// 获取当前坐标
			auto now = q.front();
			q.pop();
			
			// 标记走动的当前坐标
			st[now.x][now.y] = true;
			
			if(now == e)
			{
				// 如果到达了终点,返回步数 step
				return step;
			}
			
			// 开始想四个方向走动
			for(int i = 0;i < 4;++i)
			{
				int bx = now.x + dx[i];
				int by = now.y + dy[i];
				
				if(isRun(bx,by))
				{
					// 如果该方向坐标可以走动
					// 标记并存储好
					st[bx][by] = true;
					q.push(mk(bx,by));
				}
			}
		}
		++step;
	}
	// 如果没有到达终点,返回 -1 
	return -1;
}

inline void solve()
{
	PII s,e;
	cin >> n >> m;
	for(int i = 0;i < n;++i)
	{
		for(int j = 0;j < m;++j)
		{
			char f;
			cin >> f;
			g[i][j] = f;
			if(f == 'S')
			{
				// 记录起点坐标
				s.x = i;
				s.y = j;	
			}
			if(f == 'T')
			{
				// 记录终点坐标
				e.x = i;
				e.y = j;
			}
		}
	}
	cout << BFS(s,e) << endl;
}
signed main()
{
//	freopen("a.txt", "r", stdin);
	___G;
	int _t = 1;
//	cin >> _t;
	while (_t--)
	{
		solve();
	}

	return 0;
}

最后提交:

猜你喜欢

转载自blog.csdn.net/hacker_51/article/details/133363887