알고리즘
[백준 19238 JAVA] 스타트 택시
begong
2024. 3. 12. 00:46
반응형
dfs를 활용한 구현문제이다.
PriorityQueue를 활용해 가장 가까운, 거리가 같다면 행번호가 적은, 행도 같다면 열번호가 적은 승객을 구해 이동시킨다.
그 후 해당 승객이 원하는 지점에 데려다준다.
위의 과정을 계속 반복하면 된다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
class Point {
public int y, x;
public Point(int y, int x) {
this.y = y;
this.x = x;
}
}
class Move implements Comparable<Move> {
public int y, x;
public int cost;
public Move(int y, int x, int cost) {
this.y = y;
this.x = x;
this.cost = cost;
}
@Override
public int compareTo(Move o) {
if (this.cost != o.cost) return this.cost - o.cost;
if (this.y != o.y) return this.y - o.y;
return this.x - o.x;
}
}
public class Main {
static int N, M, FUEL;
static boolean[][] map;
static Point[][] Passengers;
static PriorityQueue<Move> pq;
static Queue<Move> q;
static int[] dy = {-1, 0, 1, 0};
static int[] dx = {0, -1, 0, 1};
public static void main(String[] args) throws IOException {
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());
map = new boolean[N + 1][N + 1];
Passengers = new Point[N + 1][N + 1];
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= N; j++) {
if (st.nextToken().equals("1")) {
map[i][j] = true;
}
}
}
st = new StringTokenizer(br.readLine());
int startTaxiY = Integer.parseInt(st.nextToken());
int startTaxiX = Integer.parseInt(st.nextToken());
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int startY = Integer.parseInt(st.nextToken());
int startX = Integer.parseInt(st.nextToken());
int destY = Integer.parseInt(st.nextToken());
int destX = Integer.parseInt(st.nextToken());
Passengers[startY][startX] = new Point(destY, destX);
}
while (M-- != 0) {
Move passenger = findPassenger(startTaxiY, startTaxiX);
if (passenger.x == 0) {
System.out.println(-1);
return;
}
FUEL -= passenger.cost;
Move goal = goGoal(passenger.y, passenger.x);
if (goal.x == 0) {
System.out.println(-1);
return;
}
FUEL -= goal.cost;
FUEL += (goal.cost * 2);
startTaxiY = goal.y;
startTaxiX = goal.x;
}
System.out.println(FUEL);
}
static Move goGoal(int y, int x) {
q = new ArrayDeque<>();
boolean[][] visit = new boolean[N + 1][N + 1];
visit[y][x] = true;
int goalY = Passengers[y][x].y;
int goalX = Passengers[y][x].x;
Passengers[y][x] = null;
q.offer(new Move(y, x, 0));
while (!q.isEmpty()) {
Move cur = q.poll();
for (int i = 0; i < 4; i++) {
int nextY = cur.y + dy[i];
int nextX = cur.x + dx[i];
if (nextY > N || nextY <= 0 || nextX > N || nextX <= 0 || visit[nextY][nextX] || map[nextY][nextX])
continue;
visit[nextY][nextX] = true;
if (cur.cost + 1 > FUEL) break;
Move temp = new Move(nextY, nextX, cur.cost + 1);
if (nextY == goalY && nextX == goalX) {
return temp;
}
q.add(temp);
}
}
return new Move(0, 0, 0);
}
static Move findPassenger(int y, int x) {
pq = new PriorityQueue<>();
boolean[][] visit = new boolean[N + 1][N + 1];
//승객을 찾기 시작하는 자리에 승객이 있으면 자기 위치 반환
if (Passengers[y][x] != null) {
return new Move(y, x, 0);
}
pq.offer(new Move(y, x, 0));
Move value = new Move(0, 0, 0);
while (!pq.isEmpty()) {
Move cur = pq.poll();
if (Passengers[cur.y][cur.x] != null) {
return new Move(cur.y, cur.x, cur.cost);
}
for (int i = 0; i < 4; i++) {
int nextY = cur.y + dy[i];
int nextX = cur.x + dx[i];
if (nextY > N || nextY <= 0 || nextX > N || nextX <= 0 || visit[nextY][nextX] || map[nextY][nextX])
continue;
visit[nextY][nextX] = true;
if (cur.cost + 1 > FUEL) break;
pq.add(new Move(nextY, nextX, cur.cost + 1));
}
}
return value;
}
}
반응형