2024年码蹄杯高职组省赛第二场 传火之路 题型:搜索

86 阅读1分钟

码题集OJ-传火之路 (matiji.net)

思想

我们把所有的传送点都放到vector里,然后就正常从起点开始向终点搜索。如果在过程中遇到传送点,那么就把传送点也放入到队列中。

code

#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int>PII;
int n, m, x1, ya;
const int N = 210;
char g[N][N];
int vis[N][N];
vector<PII> v;

struct NODE {
	int x, y, cnt;
};

int dx[] = {0,1,0,-1}, dy[] = {-1,0,1,0};
int bfs(int x, int y) {
	queue<NODE> q;
	q.push({x, y, 0});

	while (!q.empty()) {
		NODE t = q.front();
		q.pop();



		if (g[t.x][t.y]=='P')
			return t.cnt;

		for (int i = 0; i < 4; i++) {
			int tx = dx[i] + t.x, ty = dy[i] + t.y;

			if (tx < 1 || tx > n || ty < 1 || ty > m || g[tx][ty] == '#' || vis[tx][ty] == 1)
				continue;
			vis[tx][ty] = 1;

			if (g[tx][ty] == '@') {
				for (auto it : v) {
                                
                                //因为所有的传送点都放到vector里了,所以当前正在遍历的点也放到vector了。遇到当前点就跳过
					if (tx == it.first && ty == it.second || vis[it.first][it.second] == 1)
						continue;
					q.push({it.first, it.second, t.cnt + 1});
					vis[it.first][it.second] = 1;
				}
			} else
				q.push({tx, ty, t.cnt + 1});


		}
	}
	return -1;
}
signed main() {
	cin.tie(nullptr)->sync_with_stdio(false);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> g[i][j];
			if (g[i][j] == 'S')
				x1 = i, ya = j;
			if (g[i][j] == '@')
				v.push_back({i, j});
		}
	}

	cout << bfs(x1, ya);
	return 0;
}

image.png