alice132

 

2025.12.13 作业 - # P1649 [USACO07OCT] Obstacle Course S

题目描述

有一个 \(N \times N(1 \le N \le 100)\) 的场地,场地由 \(N^2\)\(1 \times 1\) 的方格组成。部分方格对于奶牛来说是无法通过的,用 \(\texttt x\) 标记出来;其他方格奶牛都可以通过,用 \(\texttt .\) 标记出来。

Bessie 发现自己位于这个场地中的位置 \(A\),并且她想要移动到位置 \(B\) 去舔那里的盐块。像奶牛这种缓慢且笨拙的生物不喜欢转弯,并且只能沿平行于方格边缘的方向移动。

对于给定的场地,求出从 \(A\)\(B\) 的路径中最少的 \(90^{\circ}\) 转弯次数。路径可以从任何方向开始和结束。

如果 Bessie 无法到达盐块的位置 \(B\),请输出 -1

输入格式

第一行一个正整数 \(N\),表示场地的长与宽。

接下来 \(N\) 行,每行一个长度为 \(N\) 的字符串,字符串每个字符为 \(\{\texttt{x},\texttt{.},\texttt{A},\texttt{B} \}\) 中的一种,表示该方格的状态。

输出格式

一行一个整数,表示 Bessie 必须进行的最小转弯次数。

输入输出样例 #1

输入 #1

3
. x A
. . .
B x .

输出 #1

2

说明/提示

【样例 \(1\) 解释】

Bessie 必须至少转弯两次:例如,Bessie 初始面朝南,向南移动一步,然后转身朝西,再向西再移动两步,接着转身朝南,最后向南移动一步进入 \(B\) 方格。(按照“上北下南左西右东”理解)

题解

按照转弯次数的规则来进行宽度优先搜索。
转弯 \(i\) 次能到达的点,再进行转弯就是转弯次数为 \(i+1\) 的点。

#include<iostream>
using namespace std;
int n,s[102][102],Q[10004][2],Ans[102][102];
int main(){
    cin>>n;
    int sx,sy,tx,ty;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++){
        char ch; scanf(" %c",&ch);
        if (ch=='A') sx=i,sy=j,s[i][j]=2;
        if (ch=='B') tx=i,ty=j,s[i][j]=1;
        if (ch=='.') s[i][j]=1;
    }
    int f=0,r=1;
    Q[r][0]=sx;Q[r][1]=sy; Ans[sx][sy]=1;
    while (f<r) {
        f++;int xx,yy;
        xx=Q[f][0];yy=Q[f][1];
        //cout<<xx<<" "<<yy<<endl;
        if (xx==tx && yy==ty) {
            cout<<Ans[tx][ty]-2<<endl;
            return 0;
        }
        for (int i=xx+1;i<=n;i++) {
            if (s[i][yy]==1 && Ans[i][yy]==0) {
                r++;Q[r][0]=i;Q[r][1]=yy;Ans[i][yy]=Ans[xx][yy]+1;
            }
            else {
                break;
            }
        }
        for (int i=yy-1;i>=1;i--) {
            if (s[xx][i]==1 && Ans[xx][i]==0) {
                r++;Q[r][0]=xx;Q[r][1]=i;Ans[xx][i]=Ans[xx][yy]+1;
            }
            else {
                break;
            }
        }


        for (int i=yy+1;i<=n;i++) {
            if (s[xx][i]==1 && Ans[xx][i]==0) {
                r++;Q[r][0]=xx;Q[r][1]=i;Ans[xx][i]=Ans[xx][yy]+1;
            }
            else {
                break;
            }
        }
        for (int i=xx-1;i>=1;i--) {
            if (s[i][yy]==1 && Ans[i][yy]==0) {
                r++;Q[r][0]=i;Q[r][1]=yy;Ans[i][yy]=Ans[xx][yy]+1;
            }
            else {
                break;
            }
        }

    }

    cout<<"-1"<<endl;
    return 0;
}

posted on 2026-01-28 22:28  alice_ss  阅读(2)  评论(0)    收藏  举报

导航