티스토리 뷰
[백준 11559번 Puyo Puyo URL]
https://www.acmicpc.net/problem/11559
문제를 풀기위해 생각해야할 것은 다음과 같습니다.
1. 상하좌우 인접한 뿌요가 4개 이상일 경우 터진다.
이 조건으로 인해 BFS탐색을 하면서 각 뿌요의 좌표를 저장해야 합니다. 뿌요의 수가 4개 이상일 경우에는
해당 뿌요들의 자리를 '.' 으로 교체하는 것이 뿌요를 터뜨리는 행위입니다.
그렇기 때문에 뿌요의 좌표와 갯수를 파악하기 쉬운 자료구조는 List입니다.
2. 한 라운드에 4개 이상인 뿌요가 여러 개 있다하더라도 연쇄반응은 1회로 간주한다.
이 조건으로 인해 반복문을 돌릴 때 연쇄반응을 카운트하는 ans 변수의 증가 타이밍을 잘 잡아야 합니다.
3. 한 라운드가 끝난 뒤에 남아있는 모든 뿌요들을 아래방향(땅)으로 모두 내린다.
이 조건 또한 타이밍을 잘 잡아야 합니다.
(4개 이상의 뿌요들은 동시에 터지기때문에 한 라운드가 끝난 뒤 땅으로 떨어뜨려야합니다.)
코드를 살펴보면,
1. sovle() 메소드 내에서 while(true) 반복을 하고 있습니다. 이때 while루프 한 번이 한 라운드이며
라운드를 빠져나오는 조건은 12 X 6 의 2차원 배열 map 모두 탐색하며 BFS를 돌린 후에
List의 사이즈가 4이상이 한번도 되지 않은 경우, 더 이상 뿌요를 터뜨릴 수 없다고 간주해 while문을 빠져나온다.
2. while문 내에서 12 X 6의 2차원 배열을 탐색하며 map[row][col] != '.' 인 경우 뿌요이므로 그 좌표부터
BFS탐색을 시작합니다.
3. 한번의 BFS 탐색이 끝나면 List의 사이즈가 4이상인지 확인하고 4이상이라면 모든 뿌요들의 좌표를 통해
map[row][col] = '.' 로 대체합니다. 그 이후 다음의 BFS탐색을 위해 List를 초기화합니다.
4. 한 라운드가 끝나면 toGround 메소드를 통해 남아있는 뿌요들을 땅으로 내립니다.
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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.StringTokenizer; public class Main { public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); public static int[] dirX = new int[] { 0, 0, -1, 1 }; public static int[] dirY = new int[] { 1, -1, 0, 0 }; public static char[][] map; public static boolean[][] visited; public static List<Node> list; public static int N = 12, M = 6, ans = 0; public static void main(String[] args) throws Exception { map = new char[N][M]; visited = new boolean[N][M]; list = new ArrayList<Node>(); for (int i = 0; i < N; i++) { String str = br.readLine(); for (int j = 0; j < M; j++) { map[i][j] = str.charAt(j); } } solve(); System.out.println(ans); } //모든 뿌요들을 땅으로 내려보내는 메소드 public static void toGround() { for (int i = 0; i < M; i++) { for (int j = N - 1; j > 0; j--) { if (map[j][i] == '.') { for (int k = j - 1; k >= 0; k--) { if (map[k][i] != '.') { map[j][i] = map[k][i]; map[k][i] = '.'; break; } } } } } } public static void solve() { while (true) { //while문을 탈출하기 위한 flag와 visited 배열 초기화 boolean flag = true; for (int i = 0; i < N; i++) Arrays.fill(visited[i], false); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if (!visited[i][j] && map[i][j] != '.') bfs(i, j); //BFS 탐색을 한번 하고 난 뒤 list의 크기가 4이상일 경우 해당 뿌요들을 터뜨린다. if (list.size() >= 4) { flag = false; for (Node node : list) { map[node.row][node.col] = '.'; } } //4개 이상 인접한 한가지 색깔의 뿌요를 터뜨렸으면 List를 초기화해야 한다. list.clear(); } } toGround(); if (flag) break; else ans += 1; } } //해당 지점부터 BFS탐색을 시작하는 메소드 public static void bfs(int startRow, int startCol) { Queue<Node> q = new LinkedList<Node>(); visited[startRow][startCol] = true; char val = map[startRow][startCol]; q.offer(new Node(startRow, startCol)); //같은 뿌요가 4개가 인접한 경우 연쇄반응이 일어나야 하므로 list에 저장시킨다. //list의 크기가 4이상이면 for문을 통해 터뜨린다. list.add(new Node(startRow, startCol)); while (!q.isEmpty()) { Node node = q.poll(); int row = node.row; int col = node.col; for (int i = 0; i < 4; i++) { int nr = row + dirX[i]; int nc = col + dirY[i]; if (isBoundary(nr, nc) && !visited[nr][nc] && map[nr][nc] == val) { list.add(new Node(nr, nc)); q.offer(new Node(nr, nc)); visited[nr][nc] = true; } } } } public static boolean isBoundary(int row, int col) { return (row >= 0 && row < N) && (col >= 0 && col < M); } } class Node { int row; int col; public Node(int row, int col) { this.row = row; this.col = col; } } | cs |
'알고리즘 문제 > 백준(BOJ)' 카테고리의 다른 글
[백준 2206번] 벽 부수고 이동하기_JAVA (0) | 2019.02.15 |
---|---|
[백준 1194번] 달이 차오른다, 가자._JAVA (1) | 2019.02.14 |
[백준 2234번] 성곽 (Java, C++) (0) | 2019.02.12 |
[백준 2667번] 단지번호붙이기_JAVA (0) | 2019.02.11 |
[백준 7576번] 토마토 (0) | 2019.02.11 |
- Total
- Today
- Yesterday
- 최소힙
- 알고스팟
- SWEA
- 삼성
- 우선순위 큐
- DFS
- 트리
- 리스트
- 자바
- 배열
- 백준
- 힙정렬
- 시뮬레이션
- 나무 재테크
- 탈주범 검거
- 중간값
- 최대힙
- 구슬 탈출2
- 14888
- 알고리즘
- 탐색
- 연산자 끼워넣기
- 힙
- 정렬
- 구현
- 큐
- BFS
- 브루트포스
- 영역 구하기
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |