W
e
l
c
o
m
e
: )

题解:CF173B Chamber of Secrets

题目分析

题意

题干很丑陋

于是自己转换了一下问题:

可以考虑成倒着跑,从 \((1, 1)\) 出发,方向向右,抵达 \((n, m+1)\)

每次遇到 # 可以以 \(1\) 的代价更换方向。其余情况均只能以原方向前进。

求最小代价。

分析

考虑分层图最短路。

  • 每一层只能沿一个方向移动,边权为 \(0\)

  • # 处向别的层连边,边权为 \(1\),表示切换方向代价为 \(1\)

貌似一般的最短路算法被卡了。

我们容易发现该图中边权为 \(0\)\(1\),考虑使用一些奇怪的技巧。

使用 01 BFS。顺带省去了建边的步骤。

时间复杂度 \(O(n)\)

Code

#include<bits/stdc++.h>
using namespace std;
#define maxn 1003

int dis[maxn][maxn][4];
string mp[maxn];

struct st
{
    int x, y, d;
    st(int X, int Y, int D):x(X), y(Y), d(D) {}
};

deque<st> q;
int dx[]={1, -1, 0, 0};
int dy[]={0, 0, 1, -1};
#define chk(i, j) ((i)&&(j)&&(i<=n)&&(j<=m))
#define mp(i, j) mp[i][j-1]

/*
   ^  
   1
<3   2>
   0
   v 
*/

void bfs(int n, int m)
{
    memset(dis, 0x3f, sizeof dis);
    q.emplace_back(1, 1, 2);
    dis[1][1][2]=0;
    while(!q.empty())
    {
        auto [x, y, p]=q.front();
        q.pop_front();
        if(!(dis[x+dx[p]][y+dy[p]][p]<=dis[x][y][p]||!chk(x+dx[p], y+dy[p])))
        {
            dis[x+dx[p]][y+dy[p]][p]=dis[x][y][p];
            q.emplace_front(x+dx[p], y+dy[p], p);
        }
        if(mp(x, y)=='#')
            for(int i=0;i<=3;i++)
            {
                if(i==p) continue;
                if(dis[x+dx[i]][y+dy[i]][i]<=dis[x][y][p]+1||!chk(x+dx[i], y+dy[i])) continue;
                dis[x+dx[i]][y+dy[i]][i]=dis[x][y][p]+1;
                q.emplace_back(x+dx[i], y+dy[i], i);
            }
    }
}

int main()
{
    int n, m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>mp[i];
    bfs(n, m+1);
    cout<<(dis[n][m+1][2]==0x3f3f3f3f?-1:dis[n][m+1][2]);
}
posted @ 2024-08-25 20:57  Jimmy-LEEE  阅读(18)  评论(0)    收藏  举报