题解:AT_abc383_c [ABC383C] Humidifier 3

题目传送门

问题陈述

AtCoder 公司办公室是一个由 \(H\) 行和 \(W\) 列组成的网格。让 \((i, j)\) 表示从上往下第 \(i\) 行和从左往上第 \(j\) 列的单元格。

每个单元格的状态用字符 \(S_{i,j}\) 表示。如果 \(S_{i,j}\)#,则表示该单元格有一堵墙;如果 \(S_{i,j}\).,则表示该单元格是一个地板;如果 \(S_{i,j}\)H,则表示该单元格在地板上放置了一个加湿器。

如果从至少一个加湿器单元格向上、向下、向左或向右移动最多 \(D\) 次而不经过墙壁,则该单元格被视为加湿单元格。需要注意的是,任何有加湿器的单元格总是加湿的。

求加湿地板单元格的数量。

思路

比较典的 \(BFS\) ,对于当前节点的四个邻居,检查其是否在网格内、是否为空白格子且未被访问。

当邻居满足条件时,放入队列等待调用。

AC代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1010;
int n,m,d,x[maxn*maxn],y[maxn*maxn],t[maxn*maxn],l,r;
bool vis[maxn][maxn];
char s[maxn][maxn];
int wx[5]={0,1,-1,0,0};
int wy[5]={0,0,0,-1,1};

int main(){
	// freopen("text.in","r",stdin);
	// freopen("text.out","w",stdout);
    cin>>n>>m>>d;
    l=1;
    for(int i=1;i<=n;i++){
        scanf("%s",s[i]+1);
        for(int j=1;j<=m;j++){
        	if(s[i][j]=='H'){//输入时往队列里放
            	x[++r]=i;
            	y[r]=j;
            	vis[i][j]=1;
        	}
        }
    }
    while(l<=r){//BFS
        if(t[l]==d){
			l++;
            continue;
        }
        for(int i=1;i<=4;i++){
            int xx = x[l] + wx[i];
            int yy = y[l] + wy[i];
            if(1<=xx && xx<=n && 1<=yy && yy<=m){
                if(s[xx][yy]== '.' && !vis[xx][yy]){
                    x[++r] = xx;
                    y[r] = yy;
                    t[r] = t[l]+1;
                    vis[xx][yy] = 1;
                }
            }
        }
        ++l;
    }
    cout<<r<<'\n';
	return 0;
}
posted @ 2024-12-17 14:10  Zheng_iii  阅读(94)  评论(0)    收藏  举报