Problem - 616C - Codeforces

Problem - 616C - Codeforces

C. The Labyrinth

如果是直接对\(*\)去跑dfs或者bfs的话无疑是会超时的

既然如此,那我们可以去对 \(.\) 跑搜索,将各个连通的 \(.\) 块标号并计算出连通块内的点的数量,然后去遍历\(*\)的时候只需要上下左右跑一下计算即可

啊,在\(bfs\)\(dfs\)的时候千万不要每次都开\(n\times m\)的空间去标记点,只需要在外面开一个就好!

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

vector<int> ans(1e6);

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m;
	cin >> n >> m;
	vector<string> g(n);
	for (auto &i : g)
		cin >> i;

	int u[] = {1, -1, 0, 0}, v[] = {0, 0, 1, -1};
	vector<vector<int>> G(n,vector<int>(m,0));
	int num = 0;

	vector vis(n, vector<bool>(m));
	auto bfs = [&](int x, int y) {
		queue<PII> Q;
		G[x][y] = num;
		Q.push({x, y});		
		i64 res = 1;
		vis[x][y] = true;
		while (Q.size()) {
			auto [x1, y1] = Q.front();
			Q.pop();
			for (int i = 0; i < 4; i ++) {
				int dx = x1 + u[i], dy = y1 + v[i];
				if (dx < 0 || dy < 0 || dx >= n || dy >= m || vis[dx][dy] || g[dx][dy] == '*')
					continue;
				Q.push({dx, dy});
				vis[dx][dy] = true;
				res ++;
				G[dx][dy] = num;
			}
		}
		return res % 10;
	};	

	for (int i = 0; i < n; i ++) {
		for (int j = 0; j < m; j ++) {
			if (g[i][j] == '.' && !G[i][j]) {
				++ num;
				ans[num] = bfs(i, j);				
			}
		}		
	}

	for (int i = 0; i < n; i ++) {
		for (int j = 0; j < m; j ++) {
			if (g[i][j] == '*') {
				int res = 1;
				int f[4]{0};				
				for (int k = 0; k < 4; k ++) {
					int dx = i + u[k], dy = j + v[k];
					if (dx < 0 || dy < 0 || dx >= n || dy >= m || g[dx][dy] == '*' )						
						continue;
					if(G[dx][dy] == f[0] || G[dx][dy] == f[1] || G[dx][dy] == f[2] || G[dx][dy] == f[3]) 
						continue;
					f[k] = G[dx][dy];
					res += ans[G[dx][dy]];
				}
				cout << res % 10;
			} else
				cout << g[i][j];
		}
		cout << '\n';

	}
	return 0;
}
posted @ 2023-09-28 13:40  Ke_scholar  阅读(13)  评论(0编辑  收藏  举报