Skip to content

Commit 59abb6a

Browse files
authored
[백준 19238] 스타트 택시 - 시뮬레이션
1 parent 65e2830 commit 59abb6a

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed

hoseok/week35/Boj19238.java

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
class Main {
5+
6+
static class Node {
7+
int r, c, count;
8+
9+
Node(int r, int c, int count) {
10+
this.r = r;
11+
this.c = c;
12+
this.count = count;
13+
}
14+
}
15+
16+
private static final int[] rows = {-1, 0, 1, 0};
17+
private static final int[] cols = {0, 1, 0, -1};
18+
private static final Map<Integer, Node> destinations = new HashMap<>();
19+
20+
private static int n, m, fuel;
21+
private static Node startNode;
22+
private static int[][] map;
23+
24+
public static void main(String[] args) throws Exception {
25+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
26+
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
27+
StringTokenizer st = new StringTokenizer(br.readLine());
28+
29+
n = Integer.parseInt(st.nextToken());
30+
m = Integer.parseInt(st.nextToken());
31+
fuel = Integer.parseInt(st.nextToken());
32+
map = new int[n][n];
33+
34+
for (int i = 0; i < n; i++) {
35+
st = new StringTokenizer(br.readLine());
36+
for (int j = 0; j < n; j++) {
37+
map[i][j] = Integer.parseInt(st.nextToken());
38+
}
39+
}
40+
41+
st = new StringTokenizer(br.readLine());
42+
startNode = new Node(
43+
Integer.parseInt(st.nextToken()) - 1,
44+
Integer.parseInt(st.nextToken()) - 1,
45+
0
46+
);
47+
48+
int count = 2;
49+
for (int i = 0; i < m; i++) {
50+
st = new StringTokenizer(br.readLine());
51+
int customerR = Integer.parseInt(st.nextToken()) - 1;
52+
int customerC = Integer.parseInt(st.nextToken()) - 1;
53+
int destinationR = Integer.parseInt(st.nextToken()) - 1;
54+
int destinationC = Integer.parseInt(st.nextToken()) - 1;
55+
destinations.put(count, new Node(destinationR, destinationC, 0));
56+
map[customerR][customerC] = count++;
57+
}
58+
59+
while (count-- > 2) {
60+
// 출발지 노드를 찾음
61+
Node findNode = bfs();
62+
// 갈 수 없다면 -1
63+
if (findNode == null || findNode.count > fuel) {
64+
fuel = -1;
65+
break;
66+
}
67+
// 출발지 노드까지가는 비용
68+
int firstAmount = findNode.count;
69+
// 도착지 노드 번호
70+
Node destinationNode = destinations.get(map[findNode.r][findNode.c]);
71+
// 출발지 노드 번호 초기화 (중복 체킹 가능성)
72+
map[findNode.r][findNode.c] = 0;
73+
// findNode를 시작 노드로 사용할 것이므로 카운터 초기화
74+
findNode.count = 0;
75+
76+
// findNode를 출발지로 도착 번호는 findCount
77+
startNode = targetBfs(findNode, destinationNode);
78+
79+
// 도착지에 갈 수 없다면 -1
80+
if (startNode == null || fuel < firstAmount + startNode.count) {
81+
fuel = -1;
82+
break;
83+
}
84+
85+
// 연료를 도착지까지 갔을때 * 2를 채움
86+
fuel = fuel - firstAmount - startNode.count + startNode.count * 2;
87+
// startNode부터 진행되므로 카운트값 초기화
88+
startNode.count = 0;
89+
}
90+
91+
bw.write(fuel + "");
92+
bw.flush();
93+
bw.close();
94+
}
95+
96+
public static Node targetBfs(Node startNode, Node destinationNode) {
97+
boolean[][] visited = new boolean[n][n];
98+
Queue<Node> que = new LinkedList<>();
99+
que.offer(startNode);
100+
visited[startNode.r][startNode.c] = true;
101+
102+
while (!que.isEmpty()) {
103+
Node curNode = que.poll();
104+
105+
if (curNode.r == destinationNode.r && curNode.c == destinationNode.c) {
106+
return curNode;
107+
}
108+
for (int i = 0; i < 4; i++) {
109+
int nextR = curNode.r + rows[i];
110+
int nextC = curNode.c + cols[i];
111+
112+
if (nextR < 0 || nextR >= n || nextC < 0 || nextC >= n) {
113+
continue;
114+
}
115+
if (!visited[nextR][nextC] && map[nextR][nextC] != 1) {
116+
visited[nextR][nextC] = true;
117+
que.offer(new Node(nextR, nextC, curNode.count + 1));
118+
}
119+
}
120+
}
121+
return null;
122+
}
123+
124+
public static Node bfs() {
125+
boolean[][] visited = new boolean[n][n];
126+
// 출발지 노드를 찾을때 가깝지만, 가장 상단 그리고 가장 좌측에 있는 노드를 찾음
127+
PriorityQueue<Node> que = new PriorityQueue<>((n1, n2) -> {
128+
if (n1.count != n2.count) {
129+
return n1.count - n2.count;
130+
}
131+
if (n1.r == n2.r) {
132+
return n1.c - n2.c;
133+
}
134+
return n1.r - n2.r;
135+
});
136+
que.offer(startNode);
137+
visited[startNode.r][startNode.c] = true;
138+
139+
while (!que.isEmpty()) {
140+
Node curNode = que.poll();
141+
if (map[curNode.r][curNode.c] >= 2) {
142+
return curNode;
143+
}
144+
for (int i = 0; i < 4; i++) {
145+
int nextR = curNode.r + rows[i];
146+
int nextC = curNode.c + cols[i];
147+
148+
if (nextR < 0 || nextR >= n || nextC < 0 || nextC >= n) {
149+
continue;
150+
}
151+
if (!visited[nextR][nextC] && map[nextR][nextC] != 1) {
152+
visited[nextR][nextC] = true;
153+
que.offer(new Node(nextR, nextC, curNode.count + 1));
154+
}
155+
}
156+
}
157+
return null;
158+
}
159+
}

0 commit comments

Comments
 (0)