P1649 [USACO07OCT] Obstacle Course S题解(BFS洪水填充算法)
题目大意
有一张长宽是 \(n\) 的图,现在要从字符 \(A\) 到字符 \(B\)。其中 \(x\) 则是障碍,问载行走的过程中最少 \(90\) 度转弯多少次。
思路
易错点
这道题有一个坑那就是先搜到的路不一定是转弯转的最少的。
常规思路
按照常规的思路因为这道题需要求路径,所以用BFS的话,就必须要搜完才行。如此一来,时间肯定得超。
优化
这里就涉及到一个民间算法叫洪水填充(不知道哪一位dalao取得名)。
具体思路就是每次选4个方向,看每个方向走到头还是否能走(不能,即四个方向都被堵完),如果能走那么就又将这个点作为起点向外继续拓展,同时打标记(即判重)。
判转弯的话就在每次拓展时加一就行了。
当所有的路径都被拓展到不能拓展时,就判断终点有没有被拓展过,有则输出转弯次数,否则输出-1。
例如
step.1
. . . x . . . .
. . . . . x . .
. . . . . . . .
. . . A . . . .
x . . . . . . x
. . . . . . x x
. . x . . . . .
step.2
. . . x . . . .
. . . * . x . .
. . . * . . . .
* * * A * * * *
x . . * . . . x
. . . * . . x x
. . x * . . . .
step.3
* . . x . . . *
* . . * . x . *
* . . * . . . *
* * * A * * * *
x . . * . . . x
* * * * . . x x
. . x * * * * *
......
code
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct node{int x,y;}c[10010];
char s;
int n,ex,ey,xx[]={0,1,0,-1},yy[]={1,0,-1,0},way[110][110];//wey是记录转弯次数
int mp[110][110];
void bfs(){
int cl=1,op=1;
while(cl<=op){
for(int i=0;i<4;i++){
for(int k=1;;k++){//枚举一个k向外持续拓展
int tx=c[cl].x+xx[i]*k,ty=c[cl].y+yy[i]*k;
if(tx>n||tx<1||ty>n||ty<1) break;
if(mp[tx][ty]==1) break;
mp[tx][ty]=1;//因为走过已经不能再走了,所以只需要当障碍处理
way[tx][ty]=way[c[cl].x][c[cl].y]+1;//次数加一
c[++op].x=tx,c[op].y=ty;
}
}
cl++;
}
if(mp[ex][ey]!=0) cout<<way[ex][ey]-1;
else cout<<-1;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
cin>>s;
if(s=='A'){c[1].x=i,c[1].y=j;}
if(s=='B'){ex=i,ey=j;}
if(s=='x') mp[i][j]=1;
}
mp[c[1].x][c[1].y]=1;
bfs();
return 0;
}
本文来自博客园,作者:Arthur_Douglas,转载请注明原文链接:https://www.cnblogs.com/wenzhihao2023/p/18023744