t < 2k时,每个点有等待和移动两种策略;
t > 2k时,不需要等待了。
另外在判断下一点是否合法时,要使用当前时刻的半径
C++ 代码
#include<iostream>
#include<queue>
using namespace std;
char m[301][301];
bool vis[301][301];
int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1};
int n,k;
struct node{
int x;
int y;
int t;
};
bool is(int x,int y,int ti){ //根据中心点和时刻判断是否合法
int det=0; //半径
if(ti < k) det= 2;
else if(ti >= k && ti < 2*k) det=1;
else if(ti >= 2*k) det= 0;
if( vis[x][y] )return false;
if(x-det<1 || x+det>n || y-det<1 || y+det>n)return false;
for(int i=x-det; i<=x+det; i++){
for(int j=y-det; j<=y+det; j++)
if(m[i][j]=='*')return false;
}
return true;
}
int bfs(){
queue<node> q;
q.push({3,3,0});
vis[3][3] = 1;
while(q.size()){
node now = q.front();
q.pop();
if(now.t<2*k) q.push({now.x, now.y, now.t+1});
for(int i=0; i<4; i++){
int nx = now.x + dx[i];
int ny = now.y + dy[i];
if(is(nx,ny,now.t)){
if(nx==n-2 && ny==n-2)return now.t+1;
vis[nx][ny] = 1;
q.push({nx, ny, now.t+1});
}
}
}
return -1;
}
int main(){
cin>>n>>k;
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++)cin>>m[i][j];
}
cout<<bfs();
return 0;
}