[agc014c]Closed Rooms

题目大意

一个网格图,从一个起点出发。
有些格子上锁。
每一轮你都可以不断往一个已解锁的四相邻格子走,最多走k次,走完后你可以选择至多k个未解锁的格子,将它们解锁。
求最少多少轮,你能走到一个边界格子。

做法

发现走的次数和可以解锁的次数相等。
因此第一轮走完,以后都不会撞锁。
bfs求出第一轮能走到的格子,然后计算到边界最小轮数。

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=800+10;
bool map[maxn][maxn],bz[maxn][maxn];
int dl[maxn*maxn][2],f[maxn][maxn],go[4][2];
int i,j,k,l,t,n,m,d,nx,ny,x,y,sx,sy,head,tail,ans;
char ch;
char get(){
    char ch=getchar();
    while (ch!='S'&&ch!='.'&&ch!='#') ch=getchar();
    return ch;
}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    fo(i,1,n){
        fo(j,1,m){
            ch=get();
            if (ch=='S'){
                sx=i;
                sy=j;
            }
            else if (ch=='#') map[i][j]=1;
        }
    }
    head=0;tail=1;
    bz[sx][sy]=1;
    dl[1][0]=sx;dl[1][1]=sy;
    go[0][0]=1;go[1][0]=-1;
    go[2][1]=1;go[3][1]=-1;
    while (head<tail){
        head++;
        nx=dl[head][0];ny=dl[head][1];
        if (f[nx][ny]==k) continue;
        fo(i,0,3){
            x=nx+go[i][0];y=ny+go[i][1];
            if (x<1||x>n||y<1||y>m) continue;
            if (bz[x][y]||map[x][y]) continue;
            bz[x][y]=1;
            f[x][y]=f[nx][ny]+1;
            tail++;
            dl[tail][0]=x;dl[tail][1]=y;
        }
    }
    ans=100000000;
    fo(i,1,n)
        fo(j,1,m)
            if (bz[i][j]){
                d=min(i-1,min(j-1,min(n-i,m-j)));
                ans=min(ans,(d%k==0)?d/k:d/k+1);
            }
    ans++;
    printf("%d\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值