[백준] 19238: 스타트 택시 - JAVA
https://www.acmicpc.net/problem/19238
풀이
빈칸과 벽이 있는 지도가 주어진다.
택시의 시작위치와 승객의 출발지와 도착지가 주어진다.
택시는 한칸 이동할 때 연료 1씩 소모하며, 승객을 태우고 이동하여 목적지에 도달하였다면
승객을 태우고 이동한 만큼의 2배 연료를 획득한다.
이동하는 중에 연료가 다 떨어지면 끝난다.
bfs탐색을 통해 택시로부터 승객까지 최소 위치를 구했고,
다시 bfs탐색으로 승객을 목적지까지 이동시켰다.
택시가 승객에 도착하거나, 목적지에 도착했을 때, 연료 체크를 하여 도중에 0이 되었는지 확인했다.
메모리: 22748KB
시간: 220ms
언어: Java 11
코드
import java.util.*;
import java.io.*;
public class Main {
static class Guest {
int sr;
int sc;
int er;
int ec;
public Guest(int sr, int sc, int er, int ec) {
this.sr = sr;
this.sc = sc;
this.er = er;
this.ec = ec;
}
}
static class Taxi {
int r;
int c;
int move;
public Taxi(int r, int c, int move) {
this.r = r;
this.c = c;
this.move = move;
}
}
static int[][] vector = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
static int n, m, fuel;
static int[][] board;
static Guest[] list;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
fuel = Integer.parseInt(st.nextToken());
board = new int[n + 1][n + 1];
for (int i = 1; i < n + 1; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j < n + 1; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
st = new StringTokenizer(br.readLine());
int sr = Integer.parseInt(st.nextToken());
int sc = Integer.parseInt(st.nextToken());
list = new Guest[m + 1];
for (int i = 1; i < m + 1; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
board[a][b] = -i;
list[i] = new Guest(a, b, c, d);
}
findGuest(sr, sc);
if (m > 0) {
fuel = -1;
}
System.out.println(fuel);
}
private static void findGuest(int sr, int sc) {
Queue<Taxi> queue = new LinkedList<>();
queue.add(new Taxi(sr, sc, 0));
boolean[][] visit = new boolean[n + 1][n + 1];
visit[sr][sc] = true;
List<Guest> tmp = new LinkedList<>();
int dist = Integer.MAX_VALUE;
while (!queue.isEmpty()) {
Taxi t = queue.poll();
if (dist < t.move) {
continue;
}
if (board[t.r][t.c] < 0) {
int idx = -board[t.r][t.c];
if (dist > t.move) {
dist = t.move;
tmp.clear();
tmp.add(list[idx]);
} else if (dist == t.move) {
tmp.add(list[idx]);
}
}
for (int i = 0; i < 4; i++) {
int nr = t.r + vector[i][0];
int nc = t.c + vector[i][1];
if (nr <= 0 || nc <= 0 || nr > n || nc > n || board[nr][nc] == 1 || visit[nr][nc]) {
continue;
}
visit[nr][nc] = true;
queue.add(new Taxi(nr, nc, t.move + 1));
}
}
Collections.sort(tmp, new Comparator<Guest>() {
@Override
public int compare(Guest o1, Guest o2) {
if (o1.sr == o2.sr) {
return o1.sc - o2.sc;
}
return o1.sr - o2.sr;
}
});
if (!tmp.isEmpty()) {
if (fuel - dist < 0) {
fuel = -1;
return;
}
Guest g = tmp.get(0);
board[g.sr][g.sc] = 0;
fuel -= dist;
goDestination(g);
}
}
private static void goDestination(Guest g) {
Queue<Taxi> queue = new LinkedList<>();
queue.add(new Taxi(g.sr, g.sc, 0));
boolean[][] visit = new boolean[n + 1][n + 1];
visit[g.sr][g.sc] = true;
while (!queue.isEmpty()) {
Taxi t = queue.poll();
if (t.r == g.er && t.c == g.ec) {
if (fuel - t.move < 0) {
fuel = -1;
return;
}
fuel += t.move;
m--;
if (m > 0) {
findGuest(t.r, t.c);
}
return;
}
for (int i = 0; i < 4; i++) {
int nr = t.r + vector[i][0];
int nc = t.c + vector[i][1];
if (nr <= 0 || nc <= 0 || nr > n || nc > n || board[nr][nc] == 1 || visit[nr][nc]) {
continue;
}
visit[nr][nc] = true;
queue.add(new Taxi(nr, nc, t.move + 1));
}
}
}
}