AGC014 C - Closed Rooms(思维+bfs)

题意:

在这里插入图片描述
在这里插入图片描述

解法:

在走k步之后才能消去k个墙,是有先后顺序的,
其实只有最开始的k步是会被墙挡住的,
因为可消去的墙的数量=可走的步数=k,所以除了第一次之后走到的地方一定没有墙.

那么bfs计算出一开始k步能够到达的非墙位置,然后直接计算出这些位置到达边界的最小距离temp,
用temp/k+(temp%k!=0)更新答案.

code:

#include <bits/stdc++.h>
#define int long long
#define PI pair<int,int>
using namespace std;
const int maxm=2e3+5;
int mark[maxm][maxm];//是否走过
int cnt[maxm][maxm];//剩余步数
char s[maxm][maxm];
int dx[]={
    
    0,0,1,-1};
int dy[]={
    
    1,-1,0,0};
int n,m,k;
int stx,sty;
int ans=1e18;
void bfs(){
    
    
    queue<PI>q;
    q.push({
    
    stx,sty});
    mark[stx][sty]=1;
    cnt[stx][sty]=k;
    while(q.size()){
    
    
        int x=q.front().first,y=q.front().second;q.pop();
        int temp=1e18;
        temp=min(temp,min(x-1,n-x));
        temp=min(temp,min(y-1,m-y));
        ans=min(ans,temp/k+(temp%k!=0));
        if(!cnt[x][y])continue;
        for(int i=0;i<4;i++){
    
    
            int xx=x+dx[i];
            int yy=y+dy[i];
            if(xx<1||xx>n||yy<1||yy>m)continue;
            if(mark[xx][yy]||s[xx][yy]=='#')continue;
            mark[xx][yy]=1;
            cnt[xx][yy]=cnt[x][y]-1;
            q.push({
    
    xx,yy});
        }
    }
}
void solve(){
    
    
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
    
    
        cin>>(s[i]+1);
        for(int j=1;j<=m;j++){
    
    
            if(s[i][j]=='S'){
    
    
                stx=i,sty=j;
            }
        }
    }
    bfs();
    cout<<ans+1<<endl;
}
signed main(){
    
    
    ios::sync_with_stdio(0);
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/114898538
今日推荐