1021 ObstacleCourse障碍训练课 优先队列+bfs+转弯

链接:https://ac.nowcoder.com/acm/contest/26077/1021
来源:牛客网

题目描述

考虑一个 N x N (1 <= N <= 100)的有1个个方格组成的正方形牧场。有些方格是奶牛们不能踏上的,它们被标记为了’x’。例如下图:

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

 

贝茜发现自己恰好在点A处,她想去B处的盐块舔盐。缓慢而且笨拙的动物,比如奶牛,十分讨厌转弯。尽管如此,当然在必要的时候她们还是会转弯的。对于一个给定的牧场,请你计算从A到B最少的转弯次数。开始的时候,贝茜可以使面对任意一个方向。贝茜知道她一定可以到达。

输入描述:

第 1行: 一个整数 N 行

2..N + 1: 行 i+1 有 N 个字符 (‘.’, ‘x’, ‘A’, ‘B’),表示每个点的状态。

输出描述:

行 1: 一个整数,最少的转弯次数。
示例1

输入

复制
3
.xA
…
Bx.

输出

复制
2

 分析

和1020一样

#include<bits/stdc++.h>
using namespace std;
const int N=1e6,M=110;
typedef pair<int,int>PII;
int h[N],e[N],ne[N],w[N],dist[N],idex,n,m,End,dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool st[N];
map<PII,int>mp;
char room[M][M];
int res=0x3f3f3f3f;
void add(int a,int b,int c){
    e[idex]=b;
    ne[idex]=h[a];
    w[idex]=c;
    h[a]=idex++;
} 
void Dijkstra(int s){
    priority_queue<PII,vector<PII>,greater<PII> >q;
    memset(dist,0x3f,sizeof(dist));
    memset(st,0,sizeof(st));
    dist[s]=0;
    q.push({0,s});
    while(!q.empty()){
        int pos=q.top().second;
        q.pop();
        if(st[pos])continue;
        st[pos]=true;
        for(int i=h[pos];i!=-1;i=ne[i]){
            if(dist[e[i]]>dist[pos]+w[i]){
                dist[e[i]]=dist[pos]+w[i];
                q.push({dist[e[i]],e[i]});
            }
        }
    }
    for(int i=0;i<4;i++){
        res=min(res,dist[End+i]);
    }
}
int main(){
    memset(h,-1,sizeof(h));
    int cnt=0,s;
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>room[i][j];
            if(room[i][j]=='A')s=cnt;
            if(room[i][j]=='B')End=cnt;
            if(room[i][j]=='x')continue;
            mp[{i,j}]=cnt;
            cnt+=4;
        }
    }
    if(n==1){cout<<0<<endl; return 0;}
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(room[i][j]=='x')continue;
            for(int k=0;k<4;k++){
                int x1=i+dir[k][0],y1=j+dir[k][1];
                if(x1>n||x1<=0||y1>n||y1<=0||room[x1][y1]=='x')continue;
                int d1=mp[{i,j}],d2=mp[{x1,y1}];
                for(int z=0;z<4;z++){
                    int xx=d1+z,yy=d2+k;
                    if(z==k)add(xx,yy,0),add(yy,xx,0);
                    else add(xx,yy,1),add(yy,xx,1);
                }
            }
        }
    }
    for(int i=0;i<=3;i++){
        int ss=s+i;
        Dijkstra(ss);
    }
    cout<<res<<endl;
}

 

posted @ 2022-08-19 13:14  er007  阅读(28)  评论(0编辑  收藏  举报