13.大胖子走迷宫 - 蓝桥云课 (lanqiao.cn)
9 5
+++++++++
+++++++++
+++++++++
+++++++++
+++++++++
***+*****
+++++++++
+++++++++
+++++++++
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
struct Node{
int x,y,time;
};
int n,k;
char board[300][300];
bool vis[300][300];
int move_hang[4]={-1,0,1,0},move_lie[4]={0,1,0,-1};
bool check(int x,int y,int t){//检查有没有撞到阻碍物,撞到就是true
if(t<k){//5*5的情况
for(int i=-2;i<=2;i++){
for(int j=-2;j<=2;j++){
if(board[x+i][y+j]=='*') return true;
}
}
}
else if(t<2*k){//3*3的情况
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
if(board[x+i][y+j]=='*') return true;
}
}
}
else{//体积为1格的情况
if(board[x][y]=='*') return true;
}
return false;
}
bool in(int x,int y,int t){//检查小明的所占体积5*5/3*3有没有出界,出界就是true
//5*5的情况
if(t<k){
if(x-2<0||y-2<0||x+2>=n||y+2>=n) return true;
else return false;
}
//3*3的情况
else if(t<2*k){
if(x-1<0||y-1<0||x+1>=n||y+1>=n) return true;
else return false;
}
//体积为1格的情况
else{
if(x<0||y<0||x>=n||y>=n) return true;
else return false;
}
return false;
}
int bfs(){
queue<Node> q;
q.push({2,2,0});
vis[2][2]=true;
while(q.size()){
auto t=q.front();
q.pop();
int tt=t.time;
//单独存原地不动(因为放for循环里的话,vis判断走没走过那里会把原地不动的情况跳过)
//只有在体积占用5*5和3*3的时候才有可能原地不动
if(tt<2*k){
q.push({t.x,t.y,tt+1});
}
for(int i=0;i<4;i++){
int xx=t.x+move_hang[i];
int yy=t.y+move_lie[i];
//出界
if(xx<0||yy<0||xx>=n||yy>=n) continue;
//走过了,再走到这个点肯定不是最优
if(vis[xx][yy]) continue;
//检查有没有撞到阻碍物,撞到就是true
if(check(xx,yy,t.time)) continue;
//检查小明的所占体积5*5/3*3有没有出界,出界就是true
if(in(xx,yy,t.time)) continue;
//走到终点
if(xx==n-3&&yy==n-3){
return tt+1;
}
vis[xx][yy]=true;
q.push({xx,yy,tt+1});
}
}
return 0;
}
void solve(){
cin>>n>>k;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>board[i][j];
}
}
cout<<bfs();
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}