洛谷 P1649 [USACO07OCT] Obstacle Course S 题解
题目链接
洛谷 P1649 [USACO07OCT] Obstacle Course S
思路分析
广搜,但有变化。对于一个方格,直上直下所需的转弯次数显然是相同的,毕竟一路直行不需要转弯。所以在对一个点出队后,我们可以向几个方向用循环遍历到不能再向前为止,把这些点全部入队。时间复杂度仍为 \(O(n^2)\)。
代码呈现
#include<bits/stdc++.h>
using namespace std;
struct node{
int x,y,d;
};
const int N=105;
int n,sx,sy,ex,ey;
int mp[N][N],dx[]={1,0,0,-1},dy[]={0,1,-1,0};
int bfs(int sx,int sy,int ex,int ey){
queue<node> q;
q.push({sx,sy,-1}),mp[sx][sy]=-1;
while (!q.empty()){
node u=q.front();q.pop();
if (u.x==ex && u.y==ey) return mp[ex][ey];
for (int i=0;i<4;++i){ // 4 个方向
if (i+u.d==3) continue; // 不走回头路
for (int nx=u.x+dx[i],ny=u.y+dy[i];
nx>=1 && nx<=n && ny>=1 && ny<=n && mp[nx][ny]!=-1;nx+=dx[i],ny+=dy[i]){ // 遍历
if (mp[nx][ny]==0x3f3f3f3f)
mp[nx][ny]=mp[u.x][u.y]+(i==u.d?0:1),q.push({nx,ny,i});
}
}
}
return -1;
}
int main(){
scanf("%d",&n);
memset(mp,0x3f,sizeof mp);
for (int i=1;i<=n;++i){
for (int j=1;j<=n;++j){
char c;scanf(" %c",&c);
if (c=='A') sx=i,sy=j;
else if (c=='B') ex=i,ey=j;
else if (c=='x') mp[i][j]=-1;
}
}
printf("%d",bfs(sx,sy,ex,ey));
return 0;
}

浙公网安备 33010602011771号