atcoder abc213e

https://atcoder.jp/contests/abc213/tasks/abc213_e

题意:

一个nxm的矩阵,从1,1走到n,m点,'.'可以直接走,#表示障碍物,可以花费1来将一个2x2的小矩阵全部变成'.',求最小的花费

思路:

相当于一个矩阵,有两种边权,所以可以考虑01bfs,如图中间这个点可以走到的点有这些,上下左右如果是'.',那么边权是0,其他情况边权都是1.
image

题解

const int N = 550;
int d[N][N];
char g[N][N];
int dx[4] = {0, 0, -1, 1};
int dy[4] = {1, -1, 0, 0};
int ddx[16] = {0, 0, 2, -2, -1, -1, -2, -2, 1, 1, -1, -1, 1, 1, 2, 2};
int ddy[16] = { -2, 2, 0, 0, -2, 2, -1, 1, -2, 2, -1, 1, -1, 1, -1, 1};
int n, m;
bool vis[N][N];
void bfs() {
    memset(d, 0x3f, sizeof d);
    d[1][1] = 0;
    deque<pii> q;
    q.push_front(mkp(1, 1));
    while (q.size()) {
        auto [x, y] = q.front();
        q.pop_front();
        if (vis[x][y]) continue;
        vis[x][y] = true;
        for (int i = 0; i < 4; i++) {
            int tx = x + dx[i], ty = y + dy[i];
            if (tx >= 1 and tx <= n and ty >= 1 and ty <= m) {
                if (g[tx][ty] == '#') {
                    if (d[x][y] + 1 < d[tx][ty]) q.push_back(mkp(tx, ty)), d[tx][ty] = d[x][y] + 1;
                } else {
                    if (d[x][y] < d[tx][ty]) q.push_front(mkp(tx, ty)), d[tx][ty] = d[x][y];
                }
            }
        }
        for (int i = 0; i < 16; i++) {
            int tx = x + ddx[i], ty = y + ddy[i];
            if (tx >= 1 and tx <= n and ty >= 1 and ty <= m) {
                if (d[x][y] + 1 < d[tx][ty]) q.push_back(mkp(tx, ty)), d[tx][ty] = d[x][y] + 1;
            }
        }
    }
}
void solve() {
    read(n, m);
    for (int i = 1; i <= n; i++) cin >> (g[i] + 1);
    bfs();
    put(d[n][m], '\n');
}
//  ###
// #####
// ##.##
// #####
//  ###
posted @ 2021-10-27 08:30  指引盗寇入太行  阅读(85)  评论(0编辑  收藏  举报