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