atcoder abc213e
https://atcoder.jp/contests/abc213/tasks/abc213_e
题意:
一个nxm的矩阵,从1,1走到n,m点,'.'可以直接走,#表示障碍物,可以花费1来将一个2x2的小矩阵全部变成'.',求最小的花费
思路:
相当于一个矩阵,有两种边权,所以可以考虑01bfs,如图中间这个点可以走到的点有这些,上下左右如果是'.',那么边权是0,其他情况边权都是1.
题解
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');
}
// ###
// #####
// ##.##
// #####
// ###