[agc014c]Closed Rooms

来源:互联网 发布:淘宝订单改地址 编辑:程序博客网 时间:2024/06/15 03:19

题目大意

一个网格图,从一个起点出发。
有些格子上锁。
每一轮你都可以不断往一个已解锁的四相邻格子走,最多走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);}
原创粉丝点击