abc311D 走迷宫之不撞南墙不回头

有个大小为n*m的二维图,.为空地,#为障碍,最外层一圈固定为障碍,起点(2,2)固定为空地,每次可以沿上下左右其中一个方向走,直到碰见障碍才能转向。问最多可以走过多少个空地?初始时方向任意,可以走多次。

bfs模拟,由于中途不能转向,把当前方向也塞到节点里。除1234分别对应上下左右外,新增一种状态5,表示遇到障碍时可以转向。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)

const int Z = 205;
int dx[] = {0, 1, -1, 0, 0, 0};
int dy[] = {0, 0, 0, -1, 1, 0};
int n, m, vis[Z][Z][6];
char s[Z][Z];
void solve() {
    cin >> n >> m;
    rep(i,1,n) rep(j,1,m) cin >> s[i][j];
    queue<tuple<int,int,int>> q;
    rep(i,1,5) {
        q.push({2,2,i});
        vis[2][2][i] = 1;
    }
    while (!q.empty()) {
        auto [x,y,d] = q.front(); q.pop();
        int nx = x + dx[d];
        int ny = y + dy[d];
        if (d == 5) {
            rep(i,1,4) if (vis[x][y][i] == 0) {
                q.push({x,y,i}); vis[x][y][i] = 1;
            }
        } else {
            if (vis[nx][ny][d] == 0) {
                if (s[nx][ny] == '.') {
                    q.push({nx,ny,d}); vis[nx][ny][d] = 1;
                } else {
                    q.push({x,y,5}); vis[x][y][5] = 1;
                }
            }
        }
    }
    int ans = 0;
    rep(i,1,n) rep(j,1,m) {
        int ok = 0;
        rep(k,1,5) if (vis[i][j][k]) ok = 1;
        ans += ok;
    }
    cout << ans << "\n";
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}
posted @ 2024-03-11 21:32  chenfy27  阅读(2)  评论(0编辑  收藏  举报