-
반응형
https://www.acmicpc.net/problem/5547
5547번: 일루미네이션
첫째 줄에 두 개의 정수 W와 H가 주어진다. (1 ≤ W, H ≤ 100) 다음 H줄에는 상근이네 집의 건물 배치가 주어진다. i+1줄에는 W개의 정수가 공백으로 구분되어 있다. j번째 (1 ≤ j ≤ w) 정수의 좌표는
www.acmicpc.net
풀이
기본적으로 BFS를 이용하여 문제를 해결할 것이다.
건물을 BFS로 돌면서, 외벽의 개수를 세어주면 되는 일인데, 여기서 외벽인지 내벽인지 판별하는것이 가장 큰 문제이다.
여러 풀이방법이 있겠지만, 건물에 대한 BFS를 돌기전에, 건물이 지어지지 않은 공간을 먼저 BFS를 돌며, 만약 외부( 범위 밖) 과 접촉한 건물이 없는 공간이라면, 이 비어있는 공간들은 모두 외부이다. 만약 BFS를 돌면서 범위 밖으로 넘어가지 못하는 공간이라면, 그 공간은 내부이다.
위의 공간에서, (1,1)과 (1,2)는 BFS를 돌면 범위 바깥과 접촉한다는것을 알 수 있으므로, 저 둘은 외부이다.
(2,3)을 보면, BFS를 전부 돌려도 범위 밖과 접촉을 하지 못하므로 내부공간이라 할 수 있다.
위와같이 범위 밖, 혹은 밖으로 갈 수 있는 공간을 외부라고 지정을 해놓은 뒤, 건물에 대한 BFS를 돌면서, 외부에 접촉한 부분을 만나면 ANSWER++를 해주면 된다.
코드
#include<iostream> #include<algorithm> #include<vector> #include<queue> using namespace std; typedef pair<int, int> pii; int maze[101][101] = { 0 }; int mv[2][6][2] = { { {-1,-1},{0,-1},{1,0},{0,1},{-1,1},{-1,0} }, { {0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,0} } }; int w, h; bool isIn(int x, int y) { return 1 <= x && x <= w && 1 <= y && y <= h; } void make_outside() { bool visited[101][101] = { 0 }; for (int i = 1; i <= h; i++) { for (int j = 1; j <= w; j++) { if (maze[j][i] == 0 && !visited[j][i]) { queue<pii> q; vector<pii> v; q.push({ j,i }); visited[j][i] = true; bool flag = false; while (!q.empty()) { int x = q.front().first; int y = q.front().second; q.pop(); v.push_back({ x,y }); for (int d = 0; d < 6; d++) { int line = y % 2; int nx = x + mv[line][d][0]; int ny = y + mv[line][d][1]; if (!isIn(nx, ny)) { flag = true; } else { if (maze[nx][ny] == 0 && !visited[nx][ny]) { q.push({ nx,ny }); visited[nx][ny] = true; } } } } if (flag) { for (pii out : v) { int x = out.first; int y = out.second; maze[x][y] = -1; } } } } } } int bfs() { int answer = 0; bool visited[101][101] = { 0 }; for (int i = 1; i <= h; i++) { for (int j = 1; j <= w; j++) { if (maze[j][i] == 1&&!visited[j][i]) { queue<pii> q; q.push({ j,i }); visited[j][i] = true; while (!q.empty()) { int x = q.front().first; int y = q.front().second; q.pop(); for (int d = 0; d < 6; d++) { int line = y % 2; int nx = x + mv[line][d][0]; int ny = y + mv[line][d][1]; if (!isIn(nx, ny)) { answer++; } else { if (maze[nx][ny] == 1&& !visited[j][i]) { q.push({ nx,ny }); visited[nx][ny] = true; } else if (maze[nx][ny] == -1) { answer++; } } } } } } } return answer; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> w >> h; for (int i = 1; i <= h; i++) { for (int j = 1; j <= w; j++) { cin >> maze[j][i]; } } make_outside(); cout << bfs() << "\n"; }
반응형'문제풀이 > 백준oj' 카테고리의 다른 글
[백준OJ] 6416번 트리인가? (0) 2021.09.25 [백준OJ] 1520번 내리막 길 (0) 2021.09.16 [백준OJ] 14575번 뒤풀이 (0) 2021.09.15 [백준OJ] 8983번 사냥꾼 (0) 2021.09.14 [백준OJ] 6443번 애너그램 (0) 2021.09.13 댓글