[BOJ] 14442 : 벽 부수고 이동하기 2

14442 : 벽 부수고 이동하기 2

풀이

BFS

벽부수고이동하기1과 다른점은 1번이 아닌 최대K번 벽을 부술수 있다는 점이다.

chk[n][m][k+1]로 잡고 BFS를 돌려주면 된다.

하지만 이때 cnt를 따로 두지 않고 chk배열에서 거리까지 계산하도록 했다.

그리고 마지막에 chk[n-1][m-1][i]에서 i를 0부터 10까지 살펴봄으로 최소거리를 구했다.

거리를 따로 두고 하려니까 더어려워서 바꿨다.

코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <cstring>
#include <queue>
using namespace std;
typedef struct s {
    int x;
    int y;
    int b;
}s;
const int dx[] = { 0,1,0,-1 };
const int dy[] = { -1,0,1,0 };
int arr[1000][1000];
//거리도 함께 첵
int chk[1000][1000][11];
int main()
{
    int n, m, k;
    cin >> n >> m>>k;
    for (int i = 0; i<n; i++) {
        for (int j = 0; j<m; j++) {
            scanf("%1d", &arr[i][j]);
        }
    }
    
    s first = { 0,0,0 };
    chk[0][0][0] = 1;
    queue<s> q;
    q.push(first);
    while (!q.empty()) {
        int x = q.front().x;
        int y = q.front().y;
        int b = q.front().b;
        q.pop();
        for (int dir = 0; dir<4; dir++) {
            int nx = x + dx[dir];
            int ny = y + dy[dir];
            if (nx >= 0 && nx<n&&ny >= 0 && ny<m) {
                if (arr[nx][ny] == 0) {
                    if (chk[nx][ny][b] == 0) {
                        q.push({ nx,ny,b});
                        chk[nx][ny][b] = chk[x][y][b]+1;
                    }
                }
                else {
                    if (b+1 <= k) {
                        if (chk[nx][ny][b + 1] == 0) {
                            q.push({ nx,ny,b + 1});
                            chk[nx][ny][b + 1] = chk[x][y][b]+1;
                        }
                    }
                }
            }
        }
    }
    int ans = -1;
    for (int i = 0; i <= k; i++) {
        if (chk[n - 1][m - 1][i] != 0) {
            if (ans == -1 || ans > chk[n - 1][m - 1][i])
                ans = chk[n - 1][m - 1][i];
        }
    }
    cout << ans;
    return 0;
}
Written on April 13, 2019