โจ ๊ตฌํ & BFS(์ต๋จ๊ฑฐ๋ฆฌ)
https://www.acmicpc.net/problem/19238
๐ ๊ณ ๋ คํด์ผํ ์
- ํ์์ ์์น์์๋ถํฐ ์น๊ฐ๊น์ง์ ์ต๋จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ค. ๐ ์๊ฐ์ด๊ณผ ์ฃผ์ !
- ์ต๋จ๊ฑฐ๋ฆฌ๊ฐ ๋์ผํ ์น๊ฐ๋ค์ด ์กด์ฌํ ๊ฒฝ์ฐ ๊ทธ ์ค ํ ๋ฒํธ๊ฐ ๊ฐ์ฅ ์์ ์น๊ฐ์, ๊ทธ๋ฐ ์น๊ฐ๋ ์ฌ๋ฌ ๋ช ์ด๋ผ๋ฉด ์ด ๋ฒํธ๊ฐ ๊ฐ์ฅ ์์ ์น๊ฐ์๊ฒ ์ด๋ํ๋ค. ๐ PriorityQueue ํ์ฉ
- ๋ฒฝ์ ์ํด ์น๊ฐ์๊ฒ ๊ฐ์ง ๋ชปํ๊ฑฐ๋ ๋ชฉ์ ์ง์ ๊ฐ์ง ๋ชปํ๋ ์ํฉ ๋ํ ๋ฐ์ํ๋ค. ๐ ๋ชฉ์ ์ง๋ก ์ด๋ํ ๋ ๊ณ ๋ คํ์ง ์์ ํ๋ ธ์๋ค..
- ํ์๊ฐ ์น๊ฐ์ ๋ชฉ์ ์ง๋ก ์ด๋ํ์์ ๋ ๊ทธ ์์น๋ ๋ค๋ฅธ ์น๊ฐ์ ์์์ ์ผ ์ ์๋ค. ๐ ์ด๋ด ๊ฒฝ์ฐ ํ์๋ ๊ตณ์ด ์ ์์ง์ฌ๋ ๋๋ค ! ์ด ์กฐ๊ฑด ๋ํ ๊ณ ๋ คํ์ง ๋ชปํด์ ํ๋ ธ์๋ค..
- ์ฐ๋ฃ๊ฐ ์ด๋ ๋์ค์ ๋จ์ด์ง๋ฉด -1์ ์ถ๋ ฅํ๊ณ ํ๋ก๊ทธ๋จ์ ์ข ๋ฃํ๋ค.
- ์ด๋ํ์ง ๋ชปํ๋ ์ํฉ์ flag์ ํตํด ์ค๊ฐ์ค๊ฐ ํ์ธํด์ผํ๋ค.
๐น๏ธ ํ์ด๋ฐฉ๋ฒ
์ฒ์ ํ ๋ ๋ฌด๋ํ๋ค ์ถ์๋๋ฐ ์๊ฐ์ด๊ณผ๊ฐ ๋ฐ์ํ๋ค. .
๊ฐ๊ฐ์ ์น๊ฐ์ ๊ฑฐ๋ฆฌ๋ฅผ ๋ชจ๋ ๊ตฌํ ํ PriorityQueue๋ฅผ ์ฌ์ฉํด ์กฐ๊ฑด์ ํด๋นํ๋ ์ด์ ์๋ฅผ ์ ํํ๋ ๋ฐฉ์์ผ๋ก ์์ฑํ๋๋ฐ ์ด ํ์ด๋ฒ์ BFS๋ฅผ ์น๊ฐ์ ์๋งํผ ๊ณ์ ๋๊ธฐ ๋๋ฌธ์ ์๊ฐ์ด๊ณผ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค.
๋จ์ํ๊ฒ ์๊ฐํ๋ฉด ๋๋ค.
- board์ ์น๊ฐ์ ๋ฒํธ(1~M)์ ๊ธฐ์ ํ๊ณ , ๋ฒฝ์ -1๋ก ๋์ฒดํ๋ค.
- ํ์ฌ ํ์์ ์์น๋ก๋ถํฐ BFS๋ฅผ ํ๋ฉฐ ์ด๋ํ ์์น๊ฐ 0๋ณด๋ค ํฌ๋ค๋ฉด ์ฆ, ์น๊ฐ์ด ์์นํด์๋ค๋ฉด PriorityQueue์ ํด๋นํ๋ ์์น์ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฃ๋๋ค.
- ํ์์ ๋ง์น๊ณ PriorityQueue๋ฅผ pollํ๋ฉด ์กฐ๊ฑด์ ์ ํฉํ ์น๊ฐ์ด ๋์จ๋ค.
- ๊ทธ ์น๊ฐ์๊ฒ ์ด๋ํ๊ณ , ์น๊ฐ์ ๋ชฉ์ ์ง๋ก ์ด๋ํ๋ค.
๐น findPassenger() : ์ต๋จ๊ฑฐ๋ฆฌ์ ์๋ ์น๊ฐ ์ฐพ๊ธฐ
// #1. ์ต๋จ๊ฑฐ๋ฆฌ์ ์๋ ์น๊ฐ ์ฐพ๊ธฐ --> ์น๊ฐ์ ๋ฒํธ ๋ฐํ
static int findPassenger() {
// ๋ง์ฝ ํ์ฌ ํ์ ์์น๊ฐ ์น๊ฐ์ ์์์ ์ด๋ผ๋ฉด ๊ทธ ์น๊ฐ์ ๋ฒํธ๋ฅผ ๋ฐํํ๋ค. (์ด๋ X)
if(board[tx][ty]>0) return board[tx][ty];
PriorityQueue<Info> pq = new PriorityQueue<>();
Queue<Info> q = new LinkedList<>();
boolean[][] visit = new boolean[N][N];
q.add(new Info(tx, ty, 0));
int dist=0;
while(!q.isEmpty()) {
Info now = q.poll();
for(int i=0; i<4; i++) {
int nx = now.x+dx[i];
int ny = now.y +dy[i];
if(inRange(nx, ny) && !visit[nx][ny] && board[nx][ny]!=-1) {
visit[nx][ny]=true;
dist = now.d+1;
// ํด๋นํ๋ ์์น์ ์น๊ฐ์ด ์๋ค๋ฉด ์น๊ฐ์ ์ ๋ณด๋ฅผ ์ฐ์ ์์ ํ์ ๋ฃ๋๋ค.
if(board[nx][ny]>0) pq.add(new Info(nx, ny, dist));
q.add(new Info(nx, ny, dist));
}
}
}
// ์น๊ฐ์๊ฒ ๊ฐ ์ ์์ ๊ฒฝ์ฐ ์ฐ์ ์์ ํ๋ ๋น์ด์๋ค. โ flag๋ก ๋ํ๋ด์ -1์ ์ถ๋ ฅํ๋๋ก ํ๋ค.
if(pq.isEmpty()) {
flag= true;
return 0;
}
Info p = pq.poll();
// ์น๊ฐ์๊ฒ ์ด๋ํ๋๋ฐ ์ฐ๋ฃ๊ฐ ๋ถ์กฑํ๋ฉด flag์ ํ์ํ๊ณ -1์ ์ถ๋ ฅํ๋๋ก ํ๋ค.
if(F<=p.d) flag=true;
// ์น๊ฐ์๊ฒ ์ด๋ํ ์ ์๋ค๋ฉด ์ฐ๋ฃ๋ฅผ ์๋ชจํ๋ค.
else F-=p.d;
// ์น๊ฐ์ ๋ฒํธ๋ฅผ ๋ฐํํ๋ค.
return board[p.x][p.y];
}
๐น moveToDest(int idx) : ์น๊ฐ์ ๋ชฉ์ ์ง๋ก ์ด๋
// #2. ์น๊ฐ์ ๋ชฉ์ ์ง๋ก ์ด๋
static int moveToDest(int idx) {
// idx = ์น๊ฐ์ ๋ฒํธ
Info dest = destination[idx];
Queue<Info> q = new LinkedList<>();
boolean[][] visit = new boolean[N][N];
visit[tx][ty]= true;
int dist=0;
q.add(new Info(tx, ty, 0));
while(!q.isEmpty()) {
Info now = q.poll();
// ์น๊ฐ์ ๋ชฉ์ ์ง์ ๋์ฐฉํ๋ค๋ฉด return
if(now.x==dest.x && now.y==dest.y) {
// ๋ง์ฝ ์ฐ๋ฃ๊ฐ ๋ถ์กฑํ๋ค๋ฉด -1์ ๋ฐํ
if(F<now.d) return -1;
// ์ด๋ํ ์ ์๋ค๋ฉด ์ฐ๋ฃ๋ฅผ ์๋ชจํ๊ณ ์ถฉ์ ํ๋ค.
else {
F-=now.d;
F+=(now.d*2);
return now.d;
}
}
for(int i=0; i<4; i++) {
int nx = now.x+dx[i];
int ny = now.y+dy[i];
if(inRange(nx, ny)&&!visit[nx][ny] && board[nx][ny]!=-1) {
visit[nx][ny] = true;
dist = now.d+1;
q.add(new Info(nx, ny, dist));
}
}
}
return -1;
}
๐น simulate() : ๋ชจ๋ ํจ์ ํตํฉ
static void simulate() {
// ์ต๋จ๊ฑฐ๋ฆฌ์ ์๋ ์น๊ฐ์ ์ฐพ๊ณ ๊ทธ ์น๊ฐ์ ๋ฒํธ๋ฅผ ๋ฐํํ๋ค.
int idx = findPassenger();
// ํ์ ~ ์น๊ฐ ๊ฑฐ๋ฆฌ๊ฐ ์ฐ๋ฃ๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ๋ค๋ฉด ์ด๋ X or ๋ฒฝ์ผ๋ก ์ธํด ์น๊ฐ์๊ฒ ๊ฐ ์ ์๋ค๋ฉด ๋
if(flag) {
resultFlag=true;
return;
}
// ํ์๋ฅผ ์ด์ ์์๊ฒ ์ด๋์ํค๊ธฐ
Info p = start[idx];
moveTaxi(p.x, p.y);
// ์น๊ฐ์ ๋ชฉ์ ์ง๋ก ์ด๋ํ์ ๋์ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฐํํ๋ค.
int dist = moveToDest(idx);
// ํ์ ~ ๋ชฉ์ ์ง ๊ฑฐ๋ฆฌ๊ฐ ์ฐ๋ฃ๋ณด๋ค ํฌ๋ฉด(= moveToDest()์ ๋ฐํ๊ฐ์ด -1์ด๋ผ๋ฉด) ์ด๋ ๋ถ๊ฐ
if(dist==-1) {
resultFlag=true;
return;
}
// ํ์๋ฅผ ๋ชฉ์ ์ง๋ก ์ด๋์ํค๊ธฐ
Info pe = destination[idx];
moveTaxi(pe.x, pe.y);
// ์น๊ฐ์ ์ด๋์์ผฐ์ผ๋ฏ๋ก ์น๊ฐ ์ ๊ฑฐ
board[p.x][p.y] = 0;
}
๐ฉ๐ป ์ ์ฒด ์ฝ๋
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
public class BOJ_19238_์คํํธํ์ {
static int N, M, F;
static int[][] board;
static int tx, ty; // ํ์์ ์์น
static Info[] start;
static Info[] destination;
static boolean flag;
static boolean resultFlag;
static int[] dx = {0, 0, -1, 1};
static int[] dy = {1, -1, 0, 0};
static class Info implements Comparable<Info>{
int x, y, d;
public Info(int x, int y, int d) {
this.x=x;
this.y=y;
this.d=d;
}
@Override
public int compareTo(Info o) {
if(d==o.d) {
if(x==o.x) return y-o.y;
else return x-o.x;
}else return d-o.d;
}
}
static void simulate() {
int idx = findPassenger();
// ํ์ ~ ์น๊ฐ ๊ฑฐ๋ฆฌ๊ฐ ์ฐ๋ฃ๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ๋ค๋ฉด ์ด๋ X or ๋ฒฝ์ผ๋ก ์ธํด ์น๊ฐ์๊ฒ ๊ฐ ์ ์๋ค๋ฉด ๋
if(flag) {
resultFlag=true;
return;
}
Info p = start[idx];
moveTaxi(p.x, p.y);
int dist = moveToDest(idx);
// ํ์ ~ ๋ชฉ์ ์ง ๊ฑฐ๋ฆฌ๊ฐ ์ฐ๋ฃ๋ณด๋ค ํฌ๋ฉด ์ด๋ ๋ถ๊ฐ
if(dist==-1) {
resultFlag=true;
return;
}
Info pe = destination[idx];
moveTaxi(pe.x, pe.y);
board[p.x][p.y] = 0;
}
// #1. ์ต๋จ๊ฑฐ๋ฆฌ์ ์๋ ์น๊ฐ ์ฐพ๊ธฐ --> ์น๊ฐ์ ๋ฒํธ ๋ฐํ
static int findPassenger() {
if(board[tx][ty]>0) return board[tx][ty];
PriorityQueue<Info> pq = new PriorityQueue<>();
Queue<Info> q = new LinkedList<>();
boolean[][] visit = new boolean[N][N];
q.add(new Info(tx, ty, 0));
int dist=0;
while(!q.isEmpty()) {
Info now = q.poll();
for(int i=0; i<4; i++) {
int nx = now.x+dx[i];
int ny = now.y +dy[i];
if(inRange(nx, ny) && !visit[nx][ny] && board[nx][ny]!=-1) {
visit[nx][ny]=true;
dist = now.d+1;
if(board[nx][ny]>0) pq.add(new Info(nx, ny, dist));
q.add(new Info(nx, ny, dist));
}
}
}
if(pq.isEmpty()) {
flag= true;
return 0;
}
Info p = pq.poll();
if(F<=p.d) flag=true;
else F-=p.d;
return board[p.x][p.y];
}
// #2. ํ์๊ฐ ํน์ ์์น (์น๊ฐ ์์น ๋๋ ๋ชฉ์ ์ง)๋ก ์ด๋
static void moveTaxi(int x, int y) {
tx = x;
ty = y;
}
// #3. ์น๊ฐ์ ๋ชฉ์ ์ง๋ก ์ด๋
static int moveToDest(int idx) {
Info dest = destination[idx];
Queue<Info> q = new LinkedList<>();
boolean[][] visit = new boolean[N][N];
visit[tx][ty]= true;
int dist=0;
q.add(new Info(tx, ty, 0));
while(!q.isEmpty()) {
Info now = q.poll();
if(now.x==dest.x && now.y==dest.y) {
if(F<now.d) return -1;
else {
F-=now.d;
F+=(now.d*2);
return now.d;
}
}
for(int i=0; i<4; i++) {
int nx = now.x+dx[i];
int ny = now.y+dy[i];
if(inRange(nx, ny)&&!visit[nx][ny] && board[nx][ny]!=-1) {
visit[nx][ny] = true;
dist = now.d+1;
q.add(new Info(nx, ny, dist));
}
}
}
return -1;
}
static boolean inRange(int x, int y) {
if(x>=0 && x<N && y>=0 && y<N) return true;
return false;
}
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
F = Integer.parseInt(st.nextToken());
board = new int[N][N];
start = new Info[M+1];
destination = new Info[M+1];
for(int i=0; i<N; i++) {
st = new StringTokenizer(br.readLine());
for(int j=0; j<N; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
if(board[i][j]==1) board[i][j]=-1;
}
}
st = new StringTokenizer(br.readLine());
tx = Integer.parseInt(st.nextToken())-1;
ty = Integer.parseInt(st.nextToken())-1;
for(int i=0; i<M; i++) {
st = new StringTokenizer(br.readLine());
int sx = Integer.parseInt(st.nextToken())-1;
int sy = Integer.parseInt(st.nextToken())-1;
int ex = Integer.parseInt(st.nextToken())-1;
int ey = Integer.parseInt(st.nextToken())-1;
board[sx][sy] = i+1;
start[i+1] = new Info(sx, sy, 0);
destination[i+1]=new Info(ex, ey, 0);
}
for(int i=0; i<M; i++) {
simulate();
if(resultFlag) break;
}
if(resultFlag) bw.write(-1 + " ");
else bw.write(F + " ");
bw.flush();
bw.close();
}
}
'์๊ณ ๋ฆฌ์ฆ > BOJ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[BOJ] 2169 ๋ก๋ด ์กฐ์ข ํ๊ธฐ - Java (1) | 2024.04.16 |
---|---|
[BOJ] 14503 ๋ก๋ด์ฒญ์๊ธฐ - Java (0) | 2024.04.11 |
[BOJ] 17837 ์๋ก์ด ๊ฒ์2 - Java (0) | 2024.03.19 |
[BOJ] 17485 ์ง์ฐ์ ๋ฌ ์ฌํ (Large) - Java (0) | 2024.03.12 |
[BOJ] 20058 ๋ง๋ฒ์ฌ ์์ด์ ํ์ด์ด์คํฐ - Java (0) | 2024.03.01 |