Skip to content

Commit 71438ba

Browse files
authored
[백준 19237] 어른 상어 - 시뮬레이션
1 parent 3fe8de1 commit 71438ba

File tree

1 file changed

+221
-0
lines changed

1 file changed

+221
-0
lines changed

hoseok/week36/Boj19237.java

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
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

Comments
 (0)