[USACO07OCT] Obstacle Course S(bfs)

[USACO07OCT] Obstacle Course S

题面翻译

N × N   ( 1 ≤ N ≤ 100 ) N\times N\ (1\le N\le 100) N×N (1N100) 方格中, x \verb!x! x 表示不能行走的格子, . \verb!.! . 表示可以行走的格子。卡门很胖,故而不好转弯。现在要从 A A A 点走到 B B B 点,请问最少要转 90 90 90 度弯多少次?

题目描述

Consider an N x N (1 <= N <= 100) square field composed of 1

by 1 tiles. Some of these tiles are impassible by cows and are marked with an ‘x’ in this 5 by 5 field that is challenging to navigate:

. . B x . 
. x x A . 
. . . x . 
. x . . . 
. . x . . 

Bessie finds herself in one such field at location A and wants to move to location B in order to lick the salt block there. Slow, lumbering creatures like cows do not like to turn and, of course, may only move parallel to the edges of the square field. For a given field, determine the minimum number of ninety degree turns in any path from A to B. The path may begin and end with Bessie facing in any direction. Bessie knows she can get to the salt lick.

输入格式

第一行一个整数 N N N,下面 N N N 行,每行 N N N 个字符,只出现字符: . , x , A , B \verb!.!,\verb!x!,\verb!A!,\verb!B! .,x,A,B,表示上面所说的矩阵格子,每个字符后有一个空格。

输出格式

一个整数:最少转弯次数。如果不能到达,输出 − 1 -1 1

样例 #1

样例输入 #1

3
. x A
. . .
B x .

样例输出 #1

2

提示

只可以上下左右四个方向行走,并且不能走出这些格子之外。开始和结束时的方向可以任意。

数据范围及约定

对于全部数据,保证 2 ≤ N ≤ 100 2\le N\le 100 2N100

思路

我们用f[i][j]表示在坐标ij的位置处的转弯次数。对于求什么最小的,我们可以试试bfs。
但这里我们得先知道一下这个:

在这里插入图片描述
所以我们做的时候就跟以往的bfs不一样,我们就得在同一个方向一口气走到黑。(因为它跟转弯有关系)

代码

//f[i][j]为当前点转弯的个数
//一口气全部扩展过去
#include<iostream>
#include<cstring>
#include<queue>

using namespace std;

const int N = 110;

struct E{
    int x,y;
};

queue<E>q;
int n;
char w[N][N];
bool st[N][N];
int f[N][N],res;
int stx,sty,edx,edy;
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};

bool check(int a,int b){
    if(a<1||b<1||a>n||b>n||w[a][b]=='x')return false;
    return true;
}

void bfs(){
    
    memset(f,0x3f,sizeof f);
    f[stx][sty]=0;
    q.push({stx,sty});
    
    st[stx][sty]=true;
    
    while(q.size()){
        E t=q.front();
        q.pop();
        
        int x=t.x,y=t.y;
        
        if(x==edx&&y==edy){
            return;
        }
        
        for(int i=0;i<4;i++){
            int a=x+dx[i],b=y+dy[i];
            while(check(a,b)){
                st[a][b]=true;
                if(f[a][b]>f[x][y]+1){
                    f[a][b]=f[x][y]+1;
                    q.push({a,b});
                }
                
                a+=dx[i],b+=dy[i];
            }
            
        }
    }
}

int main(){
    cin>>n;
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>w[i][j];
            if(w[i][j]=='A')stx=i,sty=j;
            if(w[i][j]=='B')edx=i,edy=j;
        }
    }
    
    bfs();
    
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         cout<<f[i][j]<<" ";
    //     }
    //     puts("");
    // }
    // puts("");
    
    if(f[edx][edy]==0x3f3f3f3f)puts("-1");
    else{
        cout<<f[edx][edy]-1;
    }
    
    return 0;
}
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

green qwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值