[백준/JAVA] 5547번: 일루미네이션
📖 문제
5547번: 일루미네이션
첫째 줄에 두 개의 정수 W와 H가 주어진다. (1 ≤ W, H ≤ 100) 다음 H줄에는 상근이네 집의 건물 배치가 주어진다. i+1줄에는 W개의 정수가 공백으로 구분되어 있다. j번째 (1 ≤ j ≤ w) 정수의 좌표는
www.acmicpc.net
💡 풀이 방식
• BFS
외벽과 닿는 모든 면을 정육각형으로 돌리기 위해
격자 판 숫자를 저장할 map 배열과, 벽 개수를 저장할 2차원 배열 result의 크기는 [행+2][열+2]로 설정한다.
map = new int[H+2][W+2]; // 외벽과 닿는 모든 면을 정육각형으로 돌리기 위해 +2
result = new int[H+2][W+2]; // 벽 개수 저장 리스트
visited = new boolean[H+2][W+2];
격자를 입력받는데, 건물이 있는 경우(1)는 방문 처리를 한다.
for(int i = 1 ; i <= H ; i++) {
st = new StringTokenizer(br.readLine(), " ");
for(int j = 1 ; j <= W ; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if(map[i][j] == 1)
visited[i][j] = true;
}
}
(0,0) 부터 BFS를 수행한다.
행이 홀수냐 짝수냐에 따라 인접한 6칸의 인덱스 방향이 바뀌므로 구분지어 방향을 설정한다.
// 좌, 좌상, 우상, 우, 우하, 좌하 (시계 방향)
static int[][] odd = {{0,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}}; // 홀수 행
static int[][] even = {{0,-1}, {-1,-1}, {-1,0}, {0,1}, {1,0}, {1,-1}}; // 짝수 행
인접한 칸이 격자 범위를 벗어나지 않고, 건물이 있다면(1), 현재 위치의 벽 개수에 +1한다.
인접한 칸이 격자 범위를 벗어나지 않고, 방문한 적 없고, 건물이 없는(0) 칸이라면, 해당 칸으로 탐색을 수행한다.
while(!q.isEmpty()) {
int[] now = q.poll();
for(int d = 0 ; d < 6; d++) {
int nx = 0;
int ny = 0;
if(now[0] % 2 == 1) { // 홀수 행
nx = now[0] + odd[d][0];
ny = now[1] + odd[d][1];
}
else { // 짝수 행
nx = now[0] + even[d][0];
ny = now[1] + even[d][1];
}
// 격자 범위 벗어나면 pass
if(nx < 0 || nx >= H+2 || ny < 0 || ny >= W+2) continue;
if(map[nx][ny] == 1) {
result[now[0]][now[1]]++;
continue;
}
if(!visited[nx][ny]) {
visited[nx][ny] = true;
q.add(new int[]{nx, ny});
}
}
}
💥 유의사항
행이 홀수냐 짝수냐에 따라 인접한 6칸의 인덱스 방향이 바뀌므로 구분지어 방향을 설정하는 것이 포인트,,
🔺 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
import java.util.*;
import java.io.*;
public class Main {
// 좌, 좌상, 우상, 우, 우하, 좌하 (시계 방향)
static int[][] odd = {{0,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}}; // 홀수 행
static int[][] even = {{0,-1}, {-1,-1}, {-1,0}, {0,1}, {1,0}, {1,-1}}; // 짝수 행
static int W,H;
static int[][] map, result;
static boolean[][] visited;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
W = Integer.parseInt(st.nextToken()); // 열
H = Integer.parseInt(st.nextToken()); // 행
map = new int[H+2][W+2]; // 외벽과 닿는 모든 면을 정육각형으로 돌리기 위해 +2
result = new int[H+2][W+2]; // 벽 개수 저장 리스트
visited = new boolean[H+2][W+2];
for(int i = 1 ; i <= H ; i++) {
st = new StringTokenizer(br.readLine(), " ");
for(int j = 1 ; j <= W ; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if(map[i][j] == 1) // 미리 방문처리
visited[i][j] = true;
}
}
bfs();
int answer = 0;
for(int i = 0 ; i < H+2 ; i++) {
for(int j = 0 ; j < W+2 ; j++) {
answer += result[i][j];
}
}
System.out.println(answer);
}
private static void bfs() {
Queue<int[]> q = new ArrayDeque<>();
q.add(new int[] {0, 0});
visited[0][0] = true;
while(!q.isEmpty()) {
int[] now = q.poll();
for(int d = 0 ; d < 6; d++) {
int nx = 0;
int ny = 0;
if(now[0] % 2 == 1) { // 홀수 행
nx = now[0] + odd[d][0];
ny = now[1] + odd[d][1];
}
else { // 짝수 행
nx = now[0] + even[d][0];
ny = now[1] + even[d][1];
}
// 격자 범위 벗어나면 pass
if(nx < 0 || nx >= H+2 || ny < 0 || ny >= W+2) continue;
if(map[nx][ny] == 1) {
result[now[0]][now[1]]++;
continue;
}
if(!visited[nx][ny]) {
visited[nx][ny] = true;
q.add(new int[]{nx, ny});
}
}
}
}
}
|
cs |
➕ 다른 풀이 방식
2차원 벽 개수 저장 배열을 사용하지 않고, 마지막에 계산을 통해 변수에 값을 갱신하는 식으로 푸셨다.
[백준] 5547번: 일루미네이션
오랜시간 고민 끝에 결국 풀었습니다...!
velog.io
[BOJ - JAVA] 5547 - 일루미네이션 (BFS)
# 주소 https://www.acmicpc.net/problem/5547 5547번: 일루미네이션 첫째 줄에 두 개의 정수 W와 H가 주어진다. (1 ≤ W, H ≤ 100) 다음 H줄에는 상근이네 집의 건물 배치가 주어진다. i+1줄에는 W개의 정수가 공
codingrapper.tistory.com
💦 어려웠던 점
- 행이 홀수냐 짝수냐에 따라 다르게 설정할 생각을 하지 못 했다.
- 격자 크기도 +2할 생각을 하지 못 함
🧐 새로 알게 된 내용
- 홀수 행과 짝수 행의 인접한 방향 배열을 따로 작성해 활용할 아이디어
- 이동 가능한 경우의 수가 6가지인 점!
- 벽이 있는 칸(1)을 기준으로 bfs 탐색하며 직접 길이를 구할 생각을 했는데, 벽이 없는 칸 기준으로 인접한 6방향에 맞닿은 해야 외벽에 칠해진 수를 구하는 것이 포인트..
1회독 | 2회독 | 3회독 | 4회독 | 5회독 |
V |
(참고)
[백준] 5547 일루미네이션 - BFS + 아이디어 JAVA
https://www.acmicpc.net/problem/5547 5547번: 일루미네이션 첫째 줄에 두 개의 정수 W와 H가 주어진다. (1 ≤ W, H ≤ 100) 다음 H줄에는 상근이네 집의 건물 배치가 주어진다. i+1줄에는 W개의 정수가 공백으로
passionfruit200.tistory.com
BFS_5547_일루미네이션_육각행렬
최근에 네이버 공채를 지원해보고, 코딩테스트를 보았다. 나름 준수하게 푼 것 같긴 한데, 생각보다 애먹었던 내용과 비슷했던 문제를 다시 풀어보고자 한다. 너비우선탐색을 진행하는데, 실제
cm-me0410.tistory.com