[백준 14442번[ 벽 부수고 이동하기 2

2023. 9. 18. 17:30·알고리즘 문제풀이/백준
반응형

문제 링크: https://www.acmicpc.net/problem/14442

 

14442번: 벽 부수고 이동하기 2

첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 1,000), K(1 ≤ K ≤ 10)이 주어진다. 다음 N개의 줄에 M개의 숫자로 맵이 주어진다. (1, 1)과 (N, M)은 항상 0이라고 가정하자.

www.acmicpc.net

<문제 풀이> BFS 알고리즘

 

BFS를 사용하여 최단거리를 찾을 때, 현재까지 몇 개의 벽을 부쉈는지를 체크하기 위해서 3차원 visited 배열을 다음과 같이 선언합니다.

 

visited[N][M][K] : (N,M) 좌표를 K개의 벽을 부수고 방문했을 때의 최단 거리

 

BFS의 큐에는 (좌표, 현재까지 몇 개의 벽을 부쉈는지)에 대한 정보를 담고,  다음과 같은 조건을 만족할 때 큐에 삽입합니다.

 

1. 다음 좌표가 벽일 때

벽을 부술 수 있는 횟수(K)가 남아있고 && 현재 좌표에서 벽을 부수고 다음 좌표를 방문했을 때 거리가 더 짧은 경우

 

2. 다음 좌표가 벽이 아닐 때

현재 좌표에서 다음 좌표를 방문했을 때 거리가 더 짧은 경우

 

 

 

<C++소스코드>

 
#include<iostream>
#include<cstring>
#include<queue>
#include<utility>
#include<tuple>
#include<algorithm>
using namespace std;

const int MAX_N = 1000;
const int MAX_M = 1000;
const int MAX_K = 10;
const int dx[4] = { 0, 0, 1, -1 };
const int dy[4] = { 1, -1, 0, 0 };
const int INF = 0x3f3f3f3f;
bool board[MAX_N + 1][MAX_M + 1];
int dist[MAX_N+1][MAX_M+1][MAX_K + 1];

int N, M, K;

bool OOB(int x, int y) {
    return (x < 1 || y < 1 || x > N || y > M);
}

int bfs() {
    memset(dist, 0x3f, sizeof(dist));
    queue<tuple<int, int, int> > Q;
    Q.push({ 1, 1, 0});
    dist[1][1][0] = 1;
    
    while (!Q.empty()) {
        auto cur = Q.front(); Q.pop();
        int cx, cy, cnt; tie(cx, cy, cnt) = cur;
        for (int dir = 0; dir < 4; dir++) {
            int nx = cx + dx[dir];
            int ny = cy + dy[dir];
            if (OOB(nx, ny)) continue;

            if (board[nx][ny] == 1) {
                //벽 부수기 O
                if (cnt < K &&  dist[cx][cy][cnt] + 1 < dist[nx][ny][cnt + 1]) {
                    Q.push({ nx,ny, cnt + 1 });
                    dist[nx][ny][cnt + 1] = dist[cx][cy][cnt] + 1;
                }   
            }
            else {
                if (dist[cx][cy][cnt] + 1 < dist[nx][ny][cnt]) {
                    Q.push({ nx, ny, cnt });
                    dist[nx][ny][cnt] = dist[cx][cy][cnt] + 1;
                }
            }
        }
    }

    int ans = INF;
    
    for (int i = 0; i <= K; i++) {
        ans = min(ans, dist[N][M][i]);
    }
    if (ans >= INF) return -1;
    else return ans;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    cin >> N >> M >> K;
    
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            char c; cin >> c;
            board[i][j] = c - '0';
        }
    }

    cout << bfs();
    
    return 0;
}
반응형
저작자표시 (새창열림)

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 4485] 녹색 옷 입은 애가 젤다지?  (0) 2023.09.27
[백준 5972번] 택배 배송  (0) 2023.09.19
[백준 5719번] 거의 최단 경로  (0) 2023.09.18
[백준 1774번] 우주신과의 교감  (0) 2023.09.10
[백준 2056번] 작업  (0) 2023.09.01
'알고리즘 문제풀이/백준' 카테고리의 다른 글
  • [백준 4485] 녹색 옷 입은 애가 젤다지?
  • [백준 5972번] 택배 배송
  • [백준 5719번] 거의 최단 경로
  • [백준 1774번] 우주신과의 교감
슥지니
슥지니
개발 블로그
  • 슥지니
    슥지니의 코딩노트
    슥지니
  • 전체
    오늘
    어제
    • 분류 전체보기 (199)
      • 알고리즘 문제풀이 (158)
        • 백준 (158)
      • 알고리즘 (6)
      • Node.js (2)
        • MongoDB (1)
        • 기타 (1)
      • spring (0)
      • 가상화폐 (1)
        • 바이낸스(Binance) (1)
      • C++ 테트리스 게임 (1)
      • C++ (10)
      • 안드로이드 프로그래밍 (21)
        • 코틀린 (21)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    콘솔
    C
    다이나믹 프로그래밍
    콘솔 테트리스 게임
    코틀린
    그래프
    코틀린을 활용한 안드로이드 프로그래밍
    그리디
    dp
    BFS
    우선순위 큐
    dfs
    백준
    시뮬레이션
    백트랙킹
    Kotlin
    자료구조
    알고리즘
    구현
    C++
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
슥지니
[백준 14442번[ 벽 부수고 이동하기 2
상단으로

티스토리툴바