洛谷 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;
}
posted @ 2026-01-31 16:10  CodingJuRuo  阅读(2)  评论(0)    收藏  举报