티스토리 뷰
개인적으로, 시뮬레이션 문제 중에서 제일 어려웠던 문제.....
방문 여부를 파악하기 위해 4차원 배열을 만들어야 했던 것도 생각하기 참 힘들었다.
시뮬레이션 과정은 다음과 같다.
1. 구슬을 굴린다.
- 구슬을 굴릴 때, 두 개의 구슬이 겹치든 말든 일단 굴린다.
2. 구슬을 굴리는 도중
- 만약, 구슬을 굴리는 도중 'O'을 만났다면, 멈춘다.
3. 구슬을 다 굴린 후
- 파란색 구슬이 'O'에 빠졌는지 "먼저" 확인한다. 파란색 구슬이 'O'에 빠졌다면 탐색을 종료한다.
- 파란색 구슬은 'O'에 빠지지 않고, 빨간색 구슬이 'O' 빠졌다면 정답을 출력한다.
- 어느 구슬도 'O'에 빠지지 않았다면, 두 구슬의 위치가 같은지 확인한다.
- 두 구슬의 위치가 같다면, 초기 위치의 선행 관계에 따라 위치를 조정한다.
4. 반복한다.
[소스 코드]
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Stack; import java.util.StringTokenizer; public class Main { public static final int RED = 0, BLUE = 1; public static int N, M; public static char[][] map; public static boolean[][][][] visited; public static int[] dirX = new int[] { 0, 0, 1, -1 }; // 동서남북 public static int[] dirY = new int[] { 1, -1, 0, 0 }; public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); public static void main(String[] args) throws Exception { StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken()); map = new char[N][M]; visited = new boolean[10][10][10][10]; Node node = new Node(); node.cnt = 0; for (int i = 0; i < N; i++) { String str = br.readLine(); for (int j = 0; j < M; j++) { map[i][j] = str.charAt(j); if (map[i][j] == 'R') { node.rRow = i; node.rCol = j; } else if (map[i][j] == 'B') { node.bRow = i; node.bCol = j; } } } bfs(node); } public static void bfs(Node ball) { Queue<Node> q = new LinkedList<Node>(); q.offer(ball); while (!q.isEmpty()) { Node node = q.poll(); visited[node.rRow][node.rCol][node.bRow][node.bCol] = true; //11번 이상 굴렸을 경우 -1을 출력한다. if (node.cnt >= 10) { System.out.println(-1); return; } //현재 두 구슬의 위치를 기준으로 동,서,남,북 으로 굴려본다. for (int dir = 0; dir < 4; dir++) { //파란색 구슬을 먼저 굴린다. int bnRow = node.bRow; int bnCol = node.bCol; while (map[bnRow + dirX[dir]][bnCol + dirY[dir]] != '#') { bnRow += dirX[dir]; bnCol += dirY[dir]; if (map[bnRow][bnCol] == 'O') { break; } } //그 다음, 빨간색 구슬을 굴린다. int rnRow = node.rRow; int rnCol = node.rCol; while (map[rnRow + dirX[dir]][rnCol + dirY[dir]] != '#') { rnRow += dirX[dir]; rnCol += dirY[dir]; if (map[rnRow][rnCol] == 'O') { break; } } //파란색 구슬이 'O'에 빠졌다면, 탐색을 멈춘다. if (map[bnRow][bnCol] == 'O') continue; //빨간색 구슬만 'O'에 빠졌다면, 정답을 출력한다. if (map[rnRow][rnCol] == 'O') { System.out.println(node.cnt + 1); return; } //두 구슬의 위치가 같다면, 위치를 조정한다. if (rnRow == bnRow && rnCol == bnCol) { switch (dir) { case 0: // 동 if (node.rCol > node.bCol) bnCol -= 1; else rnCol -= 1; break; case 1: // 서 if (node.rCol > node.bCol) rnCol += 1; else bnCol += 1; break; case 2: // 남 if (node.rRow > node.bRow) bnRow -= 1; else rnRow -= 1; break; case 3: // 북 if (node.rRow > node.bRow) rnRow += 1; else bnRow += 1; break; } } //두 구슬을 굴린 후의 각각의 위치가 처음 탐색하는 것이라면 큐에 넣는다. if (!visited[rnRow][rnCol][bnRow][bnCol]) { q.offer(new Node(rnRow, rnCol, bnRow, bnCol, node.cnt + 1)); } } } System.out.println(-1); } public static void showMap(int[][] map) { for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { System.out.print(map[i][j] + " "); } System.out.println(); } System.out.println(); } } class Node { int rRow; int rCol; int bRow; int bCol; int cnt; public Node(int rRow, int rCol, int bRow, int bCol, int cnt) { this.rRow = rRow; this.rCol = rCol; this.bRow = bRow; this.bCol = bCol; this.cnt = cnt; } public Node() { } } | cs |
'알고리즘 문제 > 백준(BOJ)' 카테고리의 다른 글
[백준 14502번] 연구소 :: 늦깎이 IT (0) | 2019.03.18 |
---|---|
[백준 3190번] 뱀 :: 늦깎이 IT (0) | 2019.03.18 |
[백준 14888번] 연산자 끼워넣기 :: 늦깎이 IT (0) | 2019.03.12 |
[백준 14889번] 스타트와 링크 :: 늦깎이 IT (0) | 2019.03.09 |
[백준 15686번] 치킨 배달 :: 늦깎이 IT (0) | 2019.03.09 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 최소힙
- 삼성
- 탈주범 검거
- 백준
- 자바
- 알고리즘
- 우선순위 큐
- 트리
- BFS
- 나무 재테크
- 정렬
- 알고스팟
- 구현
- 영역 구하기
- 브루트포스
- 배열
- 중간값
- 힙정렬
- SWEA
- 힙
- 탐색
- 리스트
- 시뮬레이션
- 구슬 탈출2
- DFS
- 연산자 끼워넣기
- 14888
- 최대힙
- 큐
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함