|
| 1 | +/* |
| 2 | + 상어는 같은 방향으로 동시에 이동해야 하므로, 이동할 위치를 결정하고 |
| 3 | + 한번에 이동시켜야, 갈 수 있는 방향인데 가지 못하는 경우가 생기지 않습니다. |
| 4 | +*/ |
| 5 | +import java.io.*; |
| 6 | +import java.util.*; |
| 7 | + |
| 8 | +class Main { |
| 9 | + |
| 10 | + static class Node { |
| 11 | + int r, c, dir; |
| 12 | + Node(int r, int c, int dir) { |
| 13 | + this.r = r; |
| 14 | + this.c = c; |
| 15 | + this.dir = dir; |
| 16 | + } |
| 17 | + } |
| 18 | + |
| 19 | + static class Shark { |
| 20 | + int r, c, dir; |
| 21 | + boolean isOut; |
| 22 | + |
| 23 | + Shark(int r, int c, int dir) { |
| 24 | + this.r = r; |
| 25 | + this.c = c; |
| 26 | + this.dir = dir; |
| 27 | + } |
| 28 | + |
| 29 | + public void moveTo(Node node) { |
| 30 | + this.r = node.r; |
| 31 | + this.c = node.c; |
| 32 | + this.dir = node.dir; |
| 33 | + } |
| 34 | + } |
| 35 | + |
| 36 | + static class Smell { |
| 37 | + int sharkNumber, k; |
| 38 | + |
| 39 | + Smell(int sharkNumber, int k) { |
| 40 | + this.sharkNumber = sharkNumber; |
| 41 | + this.k = k; |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + // 상하좌우 |
| 46 | + static final int[] rows = {-1, 1, 0, 0}; |
| 47 | + static final int[] cols = {0, 0, -1, 1}; |
| 48 | + |
| 49 | + static int[][][] sharkMoves; |
| 50 | + |
| 51 | + static int n, m, k; |
| 52 | + static int[][] map; |
| 53 | + static Smell[][] smellMap; |
| 54 | + static Shark[] sharks; |
| 55 | + |
| 56 | + public static void main(String[] args) throws Exception { |
| 57 | + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); |
| 58 | + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); |
| 59 | + StringTokenizer st = new StringTokenizer(br.readLine()); |
| 60 | + n = Integer.parseInt(st.nextToken()); |
| 61 | + m = Integer.parseInt(st.nextToken()); |
| 62 | + k = Integer.parseInt(st.nextToken()); |
| 63 | + sharkMoves = new int[m + 1][4][4]; |
| 64 | + sharks = new Shark[m + 1]; |
| 65 | + |
| 66 | + map = new int[n][n]; |
| 67 | + smellMap = new Smell[n][n]; |
| 68 | + for (int i = 0; i < n; i++) { |
| 69 | + st = new StringTokenizer(br.readLine()); |
| 70 | + for (int j = 0; j < n; j++) { |
| 71 | + map[i][j] = Integer.parseInt(st.nextToken()); |
| 72 | + if (map[i][j] > 0) { |
| 73 | + smellMap[i][j] = new Smell(map[i][j], k); |
| 74 | + sharks[map[i][j]] = new Shark(i, j, -1); |
| 75 | + } |
| 76 | + } |
| 77 | + } |
| 78 | + // 상어 초기 방향 입력 |
| 79 | + st = new StringTokenizer(br.readLine()); |
| 80 | + for (int i = 1; i <= m; i++) { |
| 81 | + sharks[i].dir = Integer.parseInt(st.nextToken()) - 1; |
| 82 | + } |
| 83 | + |
| 84 | + // 각 상어들의 방향당 우선순위 방향 입력 받기 |
| 85 | + for (int i = 1; i <= m; i++) { |
| 86 | + for (int j = 0; j < 4; j++) { |
| 87 | + st = new StringTokenizer(br.readLine()); |
| 88 | + for (int k = 0; k < 4; k++) { |
| 89 | + sharkMoves[i][j][k] = Integer.parseInt(st.nextToken()) - 1; |
| 90 | + } |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + int second = 0; |
| 95 | + while (true) { |
| 96 | + second++; |
| 97 | + if (second > 1000) { |
| 98 | + second = -1; |
| 99 | + break; |
| 100 | + } |
| 101 | + // 1. 상어가 이동할 위치 선정하기 |
| 102 | + Node[] nodes = findNextPosition(); |
| 103 | + // 2. 상어의 이동 시작, 이때 상어가 한칸에 둘 이상 들어있는 경우를 체크하며 더 낮은 번호의 상어만 남도록함 |
| 104 | + moveShark(nodes); |
| 105 | + // 3. 냄새 뿌리기 전에 기존 냄새 값들 1씩 감소 |
| 106 | + eraseSmell(); |
| 107 | + // 4. 냄새 뿌리기 |
| 108 | + spreadSmell(); |
| 109 | + // 5. 상어 몇마리 남았는지 체크하기 |
| 110 | + int count = 0; |
| 111 | + for (int i = 1; i <= m; i++) { |
| 112 | + if (!sharks[i].isOut) { |
| 113 | + count++; |
| 114 | + } |
| 115 | + } |
| 116 | + // 6. 1번상어만 남았을경우 종료 |
| 117 | + if (count == 1 && !sharks[1].isOut) { |
| 118 | + break; |
| 119 | + } |
| 120 | + } |
| 121 | + |
| 122 | + bw.write(second + ""); |
| 123 | + bw.flush(); |
| 124 | + bw.close(); |
| 125 | + } |
| 126 | + |
| 127 | + public static void spreadSmell() { |
| 128 | + // 자기자신의 위치로 간 경우는 냄새값을 k로 초기화 시켜줌 |
| 129 | + for (int i = 1; i <= m; i++) { |
| 130 | + Shark shark = sharks[i]; |
| 131 | + if (shark.isOut) { |
| 132 | + continue; |
| 133 | + } |
| 134 | + smellMap[shark.r][shark.c] = new Smell(i, k); |
| 135 | + } |
| 136 | + } |
| 137 | + |
| 138 | + public static void eraseSmell() { |
| 139 | + for (int i = 0; i < n; i++) { |
| 140 | + for (int j = 0; j < n; j++) { |
| 141 | + if (smellMap[i][j] == null) { |
| 142 | + continue; |
| 143 | + } |
| 144 | + smellMap[i][j].k--; |
| 145 | + if (smellMap[i][j].k == 0) { |
| 146 | + smellMap[i][j] = null; |
| 147 | + } |
| 148 | + } |
| 149 | + } |
| 150 | + } |
| 151 | + |
| 152 | + public static void moveShark(Node[] nodes) { |
| 153 | + for (int i = 1; i <= m; i++) { |
| 154 | + Shark shark = sharks[i]; |
| 155 | + Node node = nodes[i]; |
| 156 | + if (node == null) { |
| 157 | + continue; |
| 158 | + } |
| 159 | + // 다른 상어가 있다면 |
| 160 | + if (map[node.r][node.c] != 0) { |
| 161 | + // 현재 샤크가 더 작은 번호를 가지면 현재 샤크가 해당 자리 차지 |
| 162 | + if (map[node.r][node.c] > i) { |
| 163 | + map[shark.r][shark.c] = 0; |
| 164 | + shark.moveTo(node); |
| 165 | + sharks[map[node.r][node.c]].isOut = true; |
| 166 | + map[node.r][node.c] = i; |
| 167 | + } else { |
| 168 | + map[shark.r][shark.c] = 0; |
| 169 | + shark.isOut = true; |
| 170 | + } |
| 171 | + } else { |
| 172 | + map[shark.r][shark.c] = 0; |
| 173 | + map[node.r][node.c] = i; |
| 174 | + shark.moveTo(node); |
| 175 | + } |
| 176 | + } |
| 177 | + } |
| 178 | + |
| 179 | + public static Node[] findNextPosition() { |
| 180 | + Node[] nodes = new Node[m + 1]; |
| 181 | + for (int i = 1; i <= m; i++) { |
| 182 | + Shark shark = sharks[i]; |
| 183 | + if (shark.isOut) { |
| 184 | + continue; |
| 185 | + } |
| 186 | + nodes[i] = findPosition(i, shark); |
| 187 | + } |
| 188 | + return nodes; |
| 189 | + } |
| 190 | + |
| 191 | + public static Node findPosition(int sharkNumber, Shark shark) { |
| 192 | + int curDir = shark.dir; |
| 193 | + // 이동할 수 있는 위치 찾으면 즉시 반환 |
| 194 | + for (int i = 0; i < 4; i++) { |
| 195 | + int move = sharkMoves[sharkNumber][curDir][i]; |
| 196 | + int nextR = shark.r + rows[move]; |
| 197 | + int nextC = shark.c + cols[move]; |
| 198 | + |
| 199 | + if (nextR < 0 || nextR >= n || nextC < 0 || nextC >= n) { |
| 200 | + continue; |
| 201 | + } |
| 202 | + if (map[nextR][nextC] == 0 && smellMap[nextR][nextC] == null) { |
| 203 | + return new Node(nextR, nextC, sharkMoves[sharkNumber][curDir][i]); |
| 204 | + } |
| 205 | + } |
| 206 | + // 아니라면 자신이 뿌린 냄새로 이동 |
| 207 | + for (int i = 0; i < 4; i++) { |
| 208 | + int move = sharkMoves[sharkNumber][curDir][i]; |
| 209 | + int nextR = shark.r + rows[move]; |
| 210 | + int nextC = shark.c + cols[move]; |
| 211 | + |
| 212 | + if (nextR < 0 || nextR >= n || nextC < 0 || nextC >= n) { |
| 213 | + continue; |
| 214 | + } |
| 215 | + if (smellMap[nextR][nextC] != null && smellMap[nextR][nextC].sharkNumber == sharkNumber) { |
| 216 | + return new Node(nextR, nextC, sharkMoves[sharkNumber][curDir][i]); |
| 217 | + } |
| 218 | + } |
| 219 | + return null; |
| 220 | + } |
| 221 | +} |
0 commit comments