走格子(bfs+dji)

题目描述
CYJ想找到他的小伙伴FPJ,.CYJ和FPJ现在位于一个房间里,这个房间的布置可以看成一个N行M列的矩阵,矩阵内的每一个元素会是下列情况中的一种:
1.障碍区域—这里有一堵墙(用‘#’表示).
2.这是CYJ最开始在的区域(用‘C’表示).
3.这是FPJ在的区域(用‘F’表示).
4.空区域(用‘.’表示).
CYJ携带了一个所谓传送枪的东西,这是一把可以创造传送门的枪械,在每一次行动中,他可以选择下列操作中的一项:
1.移向一个相邻的格子中(上,下,左,右,不能移到墙在的格子里).这个操作要消耗一个单位的时间.
2.转向一个墙(不需要相邻,只需面向即可),向其发射传送门,传送门会留在墙内面向你的地方(至多只能同时存在两扇传送门),若墙上已经有两扇传送门,而你发射了第三扇,那么最初发射的那一扇会消失。同时,你无法在一个位置制造两扇传送门(这个操作不会耗费时间)。
3.如果他与一块墙壁相邻且面前有一扇传送门,那么他可以移动到另一扇传送门前方的格子。这个操作会耗费一个单位的时间.
CYJ想要知道自己最少需要多少时间才能够从起点(‘C’)到达终点(‘F’).
请注意:我们保证地图边缘会是一圈墙壁且一定存在‘C’,‘F’.

输入
第一行输入两个正整数 N 和 M ,(4 ≤ N,M ≤ 500).表示地图大小。
接下来的N行每行一个长度为M的字符串.表示地形。

输出
你需要输出最少的到达终点的时间,如果不能到达请输出”no”。

样例输入
【样例1】
4 4

#.F#
#C.#

【样例2】
6 8
########
#.##…F#
#C.##…#
#…#…#
#…##
########
【样例3】
4 5

#C#.#
###F#

样例输出
【样例1】
2
【样例2】
4
【样例3】
no

提示
样例2解释:
从C点(3,2)开始,我们首先向左发射传送门,再向下发射传送门,向左进入传送门,到达(5,2),向右发射传送门,向下进入传送门,到达(5,6),向上发射传送门,向右进入传送门,到达(2,6),向右移动,到达F.
在这里插入图片描述
【数据范围】
50%的数据满足:4<= N,M <=15;
100%的数据满足:4<= N,M <=500;

思路
对每个非墙点,都有至多八种方式连边,即向上下左右四个方向走一步,或向上下左右四个方向的墙面最近点移动,在连边后,直接跑dijkstra即可

代码实现

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=505;
const int M=3e5;
const int INF=0x3f3f3f3f;
const ll LINF=1e18;
const ull sed=31;
const ll mod=998244353;
const double eps=1e-7;
const double PI=3.14159265358979;
typedef pair<int,int>P;
typedef pair<double,double>Pd;

template<class T>void read(T &x)
{
    x=0;int f=0;char ch=getchar();
    while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return;
}
struct qnode
{
    int v,c;
    qnode(int _v=0,int _c=0):v(_v),c(_c){}
    bool operator < (const qnode &r) const
    {
        return c>r.c;
    }
};

struct node
{
    int to,index,w;
}E[M<<3];

int head[M],cnt,n,m;
int dis[M],dist[N][N];
P cw[4][N][N];
int ar[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
bool vis[M];
char mp[N][N];
int s,e;
queue<P>que;

inline int cal(P t)
{
    return (t.first-1)*m+t.second;
}
void add(int u,int v,int w)
{
    E[++cnt].to=v;
    E[cnt].w=w;
    E[cnt].index=head[u];
    head[u]=cnt;
}

void dji()
{
    for(int i=1;i<=n*m;i++)
    {
        dis[i]=INF;
        vis[i]=false;
    }
    priority_queue<qnode>que;
    que.push(qnode(s,0));
    dis[s]=0;
    while(!que.empty())
    {
        qnode top=que.top();
        que.pop();
        int u=top.v;
        if(vis[u]) continue;
        vis[u]=true;
        for(int i=head[u];i;i=E[i].index)
        {
            int v=E[i].to,cost=E[i].w;
            if(!vis[v] && dis[v]>dis[u]+cost)
            {
                dis[v]=dis[u]+cost;
                que.push(qnode(v,dis[v]));
            }
        }
    }
}

void bfs()
{
    while(!que.empty())
    {
        P top=que.front();
        que.pop();
        for(int i=0;i<4;i++)
        {
            int ax=top.first+ar[i][0],ay=top.second+ar[i][1];
            if(ax>0 && ay>0 && ax<=n && ay<=m && !dist[ax][ay] && mp[ax][ay]=='.')
            {
                dist[ax][ay]=dist[top.first][top.second]+1;
                que.push(P(ax,ay));
            }
        }
    }
}


int main()
{
    read(n);read(m);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",mp[i]+1);
        for(int j=1;j<=m;j++)
        {
            if(mp[i][j]=='C')
            {
                mp[i][j]='.';
                s=cal(P(i,j));
            }
            else if(mp[i][j]=='F')
            {
                mp[i][j]='.';
                e=cal(P(i,j));
            }
            else if(mp[i][j]=='#') que.push(P(i,j));
        }
    }
    bfs();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(mp[i][j]=='#') continue;
            for(int k=0;k<2;k++)
            {
                int ax=i+ar[k][0],ay=j+ar[k][1];
                if(ax>0 && ay>0 && ax<=n && ay<=m)
                {
                    if(mp[ax][ay]=='#') cw[k][i][j]=P(i,j);
                    else cw[k][i][j]=cw[k][ax][ay];
                }
            }
        }
    }
    for(int i=n;i>0;i--)
    {
        for(int j=m;j>0;j--)
        {
            if(mp[i][j]=='#') continue;
            for(int k=2;k<4;k++)
            {
                int ax=i+ar[k][0],ay=j+ar[k][1];
                if(ax>0 && ay>0 && ax<=n && ay<=m)
                {
                    if(mp[ax][ay]=='#') cw[k][i][j]=P(i,j);
                    else cw[k][i][j]=cw[k][ax][ay];
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(mp[i][j]=='#') continue;
            for(int k=0;k<4;k++)
            {
                int ax=i+ar[k][0],ay=j+ar[k][1];
                if(k>=2 && ax>0 && ay>0 && ax<=n && ay<=m && mp[ax][ay]=='.')
                {
                    add(cal(P(ax,ay)),cal(P(i,j)),1);
                    add(cal(P(i,j)),cal(P(ax,ay)),1);
                }
                if(cw[k][i][j]!=P(i,j)) add(cal(P(i,j)),cal(cw[k][i][j]),dist[i][j]);
            }
        }
    }
    dji();
    if(dis[e]==INF) puts("no");
    else printf("%d\n",dis[e]);
    return 0;
}

发布了235 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43935894/article/details/105623155
今日推荐