[백준 16946번 C/C++] 벽 부수고 이동하기 4
[백준 16946번 C/C++] 벽 부수고 이동하기 4
https://www.acmicpc.net/problem/16946
16946번: 벽 부수고 이동하기 4
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 한 칸에서 다른 칸으로 이동하려면, 두 칸이 인접해야 한다. 두 칸이
www.acmicpc.net
해결전략
너비우선탐색 BFS
풀이전략
- 0 위치 한 곳에서 BFS를 실행한다.
- 인접한 0을 모두 방문하고 카운팅(cnt)하고 방문체크한다.
-
// 빈 공간이고 방문하지 않았다면 if (v[ny][nx] == 0 && ch[ny][nx] == 0) { Q.push({ ny, nx }); ch[ny][nx] = 1; cnt++; }
-
- 인접한 wall(1이상의 값의 위치)을 새로운 큐(wallQ)에 담고 방문체크한다.
-
// 벽이고 방문하지 않았다면 else if (v[ny][nx] >= 1 && visited_Wall[ny][nx] == 0) { wallQ.push({ ny, nx }); visited_Wall[ny][nx] = 1; // 벽 방문 체크 }
-
- 인접한 wall에 cnt한 값을 더해준다.
-
// 인접한 wall에 방금 방문한 0들을 카운트(cnt)한 값을 더함(=벽에 인접한 빈 공간의 개수를 더함) while(!wallQ.empty()) { int yy = wallQ.front().first; int xx = wallQ.front().second; wallQ.pop(); v[yy][xx] += cnt; // 벽에 인접한 빈 공간의 개수를 더함 visited_Wall[yy][xx] = 0; // 벽 방문 체크를 초기화 }
-
- 인접한 0을 모두 방문하고 카운팅(cnt)하고 방문체크한다.
- 방문한적이 없는 0 위치에서 위 과정을 반복한다
for (int y = 0; y < n; y++) {
for (int x = 0; x < m; x++)
{
if (v[y][x] == 0 && ch[y][x] == 0) {
BFS(y, x);
}
}
}
정답 코드
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int dirY[4] = { -1, 0, 1, 0 };
int dirX[4] = { 0, -1, 0, 1 };
int n, m;
vector<vector<int>> v;
vector<vector<int>> ch; // 방문 여부를 체크할 벡터
vector<vector<int>> visited_Wall; // 벽에 대한 방문 여부를 체크할 벡터
void BFS(int y, int x) // BFS를 이용해서 벽에 인접한 빈 공간을 탐색하고, 그 크기를 구하는 함수
{
queue<pair<int, int>> Q;
Q.push({ y, x });
ch[y][x] = 1; // 방문 체크
int cnt = 1; // 방문한 빈 공간의 개수
queue<pair<int, int>> wallQ; // 벽의 위치를 저장할 큐
while (!Q.empty())
{
int y = Q.front().first;
int x = Q.front().second;
Q.pop();
for (int i = 0; i < 4; i++) {
int ny = y + dirY[i];
int nx = x + dirX[i];
if (ny < 0 || n <= ny || nx < 0 || m <= nx) continue;
// 빈 공간이고 방문하지 않았다면
if (v[ny][nx] == 0 && ch[ny][nx] == 0) {
Q.push({ ny, nx });
ch[ny][nx] = 1;
cnt++;
}
// 벽이고 방문하지 않았다면
else if (v[ny][nx] >= 1 && visited_Wall[ny][nx] == 0) {
wallQ.push({ ny, nx });
visited_Wall[ny][nx] = 1; // 벽 방문 체크
}
}
}
// 인접한 wall에 방금 방문한 0들을 카운트(cnt)한 값을 더함(=벽에 인접한 빈 공간의 개수를 더함)
while(!wallQ.empty())
{
int yy = wallQ.front().first;
int xx = wallQ.front().second;
wallQ.pop();
v[yy][xx] += cnt; // 벽에 인접한 빈 공간의 개수를 더함
visited_Wall[yy][xx] = 0; // 벽 방문 체크를 초기화
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
v.resize(n, vector<int>(m));
ch.resize(n, vector<int>(m));
visited_Wall.resize(n, vector<int>(m));
string input;
for (int y = 0; y < n; y++) {
cin >> input;
for (int x = 0; x < m; x++) {
v[y][x] = input[x] - '0';
}
}
// 모든 빈 공간에 대해 BFS 실행
for (int y = 0; y < n; y++) {
for (int x = 0; x < m; x++)
{
if (v[y][x] == 0 && ch[y][x] == 0) {
BFS(y, x);
}
}
}
// 출력
for (int y = 0; y < n; y++) {
for (int x = 0; x < m; x++) {
cout << v[y][x] % 10;
}
cout << "\n";
}
return 0;
}
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 13334번 C/C++] 철로 (2) | 2024.02.05 |
---|---|
[백준 14725번 C/C++] 개미굴 (0) | 2024.02.04 |
[백준 17387번 C/C++] 선분 교차 2 (0) | 2024.01.30 |
[백준 1025번 C/C++] 제곱수 찾기 (0) | 2024.01.30 |
[백준 17404번 C/C++] RGB거리 2 (1) | 2024.01.26 |
댓글
이 글 공유하기
다른 글
-
[백준 13334번 C/C++] 철로
[백준 13334번 C/C++] 철로
2024.02.05 -
[백준 14725번 C/C++] 개미굴
[백준 14725번 C/C++] 개미굴
2024.02.04 -
[백준 17387번 C/C++] 선분 교차 2
[백준 17387번 C/C++] 선분 교차 2
2024.01.30 -
[백준 1025번 C/C++] 제곱수 찾기
[백준 1025번 C/C++] 제곱수 찾기
2024.01.30