题解:AT_abc383_c [ABC383C] Humidifier 3
题目大意
给你一个 # 代表墙壁,. 代表空地,H 代表加湿器。
若一个方格可以由至少一个加湿器
求:加湿方格的个数。
题目分析
有一个很明显的思路,从每一个加湿器一个一个进行 BFS。但显然会超时。其实,我们可以把所有加湿器放进同一个队列里,这样只需要一次 BFS,就求出来加湿方格的个数了。
代码
#include <bits/stdc++.h>
#define ft first
#define sd second
#define endl '\n'
#define pb push_back
#define md make_pair
#define gc() getchar()
#define pc(ch) putchar(ch)
#define umap unordered_map
#define pque priority_queue
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 bint;
typedef pair<int, int> pii;
typedef pair<pii, int> pi1;
typedef pair<pii, pii> pi2;
const int INF = 0x3f3f3f3f;
inline ll read()
{
ll res = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : f), ch = getchar();
while (ch >= '0' && ch <= '9') res = res * 10 + ch - '0', ch = getchar();
return res * f;
}
inline void write(ll x)
{
if (x < 0) x = -x, pc('-');
if (x > 9) write(x / 10);
pc(x % 10 + '0');
}
inline void writech(ll x, char ch) { write(x), putchar(ch); }
const int N = 1e3 + 5;
char ch[N][N];
int n, m, d;
bool check(int x, int y) { return 1 <= x && x <= n && 1 <= y && y <= m; } // 判断这个点有没有出界
int dx[] = {1, -1, 0, 0}; // 方向数组
int dy[] = {0, 0, 1, -1};
bool vis[N][N];
int main()
{
queue<pi1> q; pi1 tmp;
n = read(), m = read(), d = read();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
cin >> ch[i][j];
if (ch[i][j] == 'H') // 加湿方格
{
tmp = md(md(i, j), 0);
q.push(tmp);
}
}
while (!q.empty())
{
tmp = q.front(); q.pop();
int x = tmp.ft.ft, y = tmp.ft.sd, step = tmp.sd;
if (step > d) break;
vis[x][y] = true; // 标记
for (int i = 0; i < 4; i++)
{
int nx = x + dx[i], ny = y + dy[i];
if (!check(nx, ny) || ch[nx][ny] == '#' || vis[nx][ny]) continue; // 不合法
pi1 ttmp = md(md(nx, ny), step + 1);
q.push(ttmp); // 入队
}
}
int ans = 0; // 统计加湿方格的个数
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
ans += vis[i][j];
write(ans);
return 0;
}