평소와 마찬가지로… 일단 이 문제를 처음 풀었을 때의 코드를 첨부함…
//벽 부수고 이동하기 - 골드 3
#include <bits/stdc++.h>
using namespace std;
typedef tuple<int, int, bool> tib;
vector<vector<int>> arr;
queue<tib> q;
int cnt = 0;
int x[4] = {-1, 1, 0, 0}, y[4] = {0, 0, -1, 1};
int n, m;
vector<vector<bool>> visited;
bool possible;
void solve() {
q.push({0, 0, false});
while (!q.empty()) {
int l = q.size();
cnt++;
for (int k = 0; k < l; k++) {
tib cur = q.front();
q.pop();
int cx = get<0>(cur), cy = get<1>(cur);
if (cx == n-1 && cy == m-1) {
possible = true;
return;
}
visited[cx][cy] = true;
for (int i = 0; i < 4; i++) {
bool flag = get<2>(cur);
int nx = cx + x[i], ny = cy + y[i];
if (nx <0 || nx >= n || ny < 0 || ny >= m || visited[nx][ny]) continue;
if (arr[nx][ny] && flag) {
continue;
}
if (arr[nx][ny]) {
flag = true;
}
q.push({nx, ny, flag});
}
}
}
}
int main() {
cin >> n >> m;
arr.assign(n, vector<int> (m, 0));
visited.assign(n, vector<bool> (m, false));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
char c; cin >> c;
arr[i][j] = c-'0';
}
}
solve();
if (!possible) cout << -1;
else cout << cnt;
}
간단함
평범한 bfs 탐색을 해주는데 q에 집어넣는 값에 bool 값을 추가함 이 bool 값은 벽을 부순 적이 있는지 없는지를 저장하는 값임 그래서 만약 벽을 만났을 경우에 부순 적이 있다? -> continue 없다 -> true로 바꿔주고 진행
이라는 간단한 로직인데… 사실 잘못되었다!
문제는 visited에 있음… 이제 벽을 부숨으로 인해서… 다양한 가능세계가 만들어지잖음?? (표현이 거시기하지만 이 말밖에 떠오르지 않는다…) 그래서 벽을 부쉈는데 특정 칸에 도착하는 세계관과? 부수지 않았음에도 특정 칸에 도착하는 세계관이 모두 존재할 수 있다는 거임 근데 평범한 bfs는 한 번이라도 방문한 적이 있으면 바로 제껴버리기 때문에 만약 후자의 경우라면? 아예 다른 세계관의 케이스이기 때문에 고려를 해주고 넘어가야함에도 불구하고 제껴지는 거임!
이런 큰 문제가 있었고 따라서 이 점을 수정해야겠다고 생각을 함…