백준 2206 벽 부수고

https://www.acmicpc.net/problem/2206


백준 2206 벽 부수고 1

이 문제는 일반적인 BFS 검색 문제와 크게 다르지 않으나 벽(1)을 한 번만 이동할 수 있다는 조건에서 큰 차이가 있습니다.

그리고 그 조건은 조금 더 어렵게 만들었습니다.

입력을 2D 배열로 가져오고 찾고자 하는 최단 경로를 3D 배열로 만들어서 해결했습니다.

벽을 부수는 것이 최단 경로일 수 있고, 벽을 부수지 않는 것이 최단 경로일 수 있기 때문입니다.

d(x)(y)(z) = x 행 y 열 z(부서진 벽의 수)로 볼 수 있습니다.

따라서 기존 BFS 검색에서 벽을 허무는 조건을 추가할 수 있습니다.

#include <iostream>
#include <vector>
#include <queue>
#include <tuple>
using namespace std;
int a(1001)(1001);    // 입력
int d(1001)(1001)(2); // d(x)(y)(z) : x,y (행, 열), z (벽을 부순 횟수)
int mov(4)(2) = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

// 빈칸 -> 빈칸 (ok), 빈 칸 -> 벽 (가능할 수 있다.

), 벽 -> 빈 칸(항상), 벽->벽(x, 벽을 한번만 부술 시 있기 때문이다.

) // 정점 (r, c(위치), k(벽을 부순 횟수)) int main() { int n, m; cin >> n >> m; for (int i = 0; i < n; i++) { string input; cin >> input; for (int j = 0; j < m; j++) { a(i)(j) = input(j) - '0'; } } queue<tuple<int, int, int>> q; d(0)(0)(0) = 1; q.push(make_tuple(0, 0, 0)); while (!
q.empty()) { int x = get<0>(q.front()); int y = get<1>(q.front()); int z = get<2>(q.front()); q.pop(); for (int i = 0; i < 4; i++) { int r = x + mov(i)(0); int c = y + mov(i)(1); if (r >= 0 && r < n && c >= 0 && c < m) { if (a(r)(c) == 0 && d(r)(c)(z) == 0) { d(r)(c)(z) = d(x)(y)(z) + 1; q.push(make_tuple(r, c, z)); } // 벽을 부술 경우 if (z == 0 && a(r)(c) == 1 && d(r)(c)(z + 1) == 0) { d(r)(c)(z + 1) = d(x)(y)(z) + 1; q.push(make_tuple(r, c, z + 1)); } } } } if (d(n - 1)(m - 1)(0) !
= 0 && d(n - 1)(m - 1)(1) !
= 0) { cout << min(d(n - 1)(m - 1)(0), d(n - 1)(m - 1)(1)); } else if (d(n - 1)(m - 1)(0) !
= 0) { cout << d(n - 1)(m - 1)(0); } else if (d(n - 1)(m - 1)(1) !
= 0) { cout << d(n - 1)(m - 1)(1); } else { cout << -1; } }

d(n-1)(m-1)(0): 벽을 뚫지 않고 n행 m열로 이동

d(n-1)(m-1)(1): 행 n과 열 m에 도달하려면 벽을 한 번 부수고 이동합니다.