Problem Solving/BOJ

[백준 1194번] [BFS / 비트마스킹] 달이 차오른다, 가자.

  • -
728x90
반응형

문제에서 이동 횟수의 최솟값을 묻는 상황이므로, BFS를 바로 떠올려주면 된다.

다만, 이 문제에서 되게 독특한 지점은 각 이동하는 상황에서 키를 가지고 있는지 여부가 굉장히 중요하다. 따라서 키를 가지고 있는지 여부를 set으로 넘겨줘도 되지만, 비트마스킹을 활용해주면 숫자 하나로 모든 것을 판단할 수 있게 된다.

 

추가적으로 visited도 신경써야 하는데, 키가 달라진다면 기존에 방문했던 곳이라도 양상이 달라질 수 있기 때문에 visited를 3차원으로 잡아주면 된다. 다음 문제와 비슷하게 느낌을 받았으면 충분하다. (위 문제도 단순히 같은 위치를 방문한다고 해서 같은 의미는 아니므로 차원을 1개 늘렸다.)

https://viyoung.tistory.com/334

 

[백준 2206번] [BFS] 벽 부수고 이동하기

Approach 표면적으로 보면 BFS 대표 유형과 유사해보인다. 다만, 일반적인 문제와 달리 1칸 벽을 뚫을 수 있다는 측면을 추가적으로 고려해야한다는 점에서 어렵다고 할 수 있다. 잘 생각해보면, 무

viyoung.tistory.com

 

추가적으로 구현 과정에서 UTF-8의 성질을 이용하면 조금 더 쉽게 키와 문을 매핑지을 수 있다.

#include <bits/stdc++.h> #define fastio ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0) using namespace std; typedef pair<int, int> pii; typedef pair<pii, int> piii; int n, m; pii start_point; int move_x[4] = {-1, 1, 0, 0}; int move_y[4] = {0, 0, -1, 1}; char r[50][50]; bool visited[50][50][1 << 6]; int main(void){ fastio; memset(visited, 0, sizeof(visited)); set<pii> end_point; cin >> n >> m; for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ cin >> r[i][j]; if(r[i][j] == '0'){ start_point = make_pair(i, j); } else if(r[i][j] == '1'){ end_point.insert(make_pair(i, j)); } } } queue<piii> q; q.push(make_pair(start_point, 0)); visited[start_point.first][start_point.second][0] = 1; int move_num = 0; while(!q.empty()){ int q_size = q.size(); for(int i = 0; i < q_size; i++){ int x = q.front().first.first; int y = q.front().first.second; int key = q.front().second; if(end_point.find(q.front().first) != end_point.end()){ cout << move_num << "\n"; return 0; } q.pop(); for(int j = 0; j < 4; j++){ int dx = x + move_x[j]; int dy = y + move_y[j]; if(dx < 0 || dx >= n || dy < 0 || dy >= m) continue; else{ if(!visited[dx][dy][key]){ if(r[dx][dy] == '.' || r[dx][dy] == '1' || r[dx][dy] == '0'){ q.push(make_pair(make_pair(dx, dy), key)); visited[dx][dy][key] = 1; } else if(r[dx][dy] == '#') continue; else if (r[dx][dy] >= 'a' && r[dx][dy] <= 'f'){ int to = key | (1 << (r[dx][dy] - 'a')); q.push(make_pair(make_pair(dx, dy), to)); visited[dx][dy][to] = 1; } else if(r[dx][dy] >= 'A' && r[dx][dy] <= 'F'){ if(key & (1 << (r[dx][dy] - 'A'))){ q.push(make_pair(make_pair(dx, dy), key)); visited[dx][dy][key] = 1; } } } } } } move_num++; } cout << -1 << "\n"; return 0; }
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.