코드트리 | 코딩테스트 준비를 위한 알고리즘 정석
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
www.codetree.ai
아이디어
- 시뮬레이션
- BFS 역추적
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int n, m;
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static ArrayList<int[]> bases = new ArrayList<int[]>();
static person[] people;
static boolean[][] road;
static boolean[] arrive;
static int[][] dir = {{-1,0},{0,-1},{0,1},{1,0}};
static class person {
int r, c, target_r, target_c;
public person(int r, int c, int target_r, int target_c) {
this.r = r;
this.c = c;
this.target_r = target_r;
this.target_c = target_c;
}
public void goBase() {
PriorityQueue<int[]> pq = new PriorityQueue<int[]>((a,b) -> {
if(a[0] == b[0]) {
if(a[1] == b[1]) {
return a[2] - b[2];
} else return a[1] - b[1];
} else return a[0] - b[0];
});
Queue<int[]> q = new LinkedList<int[]>();
int[][] dis = new int[n][n];
q.add(new int[] {target_r, target_c});
dis[target_r][target_c] = 1;
while(!q.isEmpty()) {
int[] now = q.poll();
for (int k = 0; k < 4; k++) {
int nr = now[0] + dir[k][0];
int nc = now[1] + dir[k][1];
if(nr<0||nc<0||nr>=n||nc>=n) continue;
if(road[nr][nc]) continue;
if(dis[nr][nc]>0) continue;
q.add(new int[] {nr, nc});
dis[nr][nc] = dis[now[0]][now[1]] + 1;
}
}
for(int[] b : bases) {
int di = dis[b[0]][b[1]];
if(di!=0) pq.add(new int[] {di, b[0], b[1]});
}
int[] target_base = pq.poll();
this.r = target_base[1];
this.c = target_base[2];
for(int i=0; i<bases.size(); i++) {
int[] now = bases.get(i);
if(now[0] == this.r && now[1] == this.c) {
bases.remove(i);
road[now[0]][now[1]] = true;
break;
}
}
}
public void move() {
Queue<int[]> q = new LinkedList<int[]>();
q.add(new int[] {target_r,target_c});
int[][] trace = new int[n][n];
trace[target_r][target_c] = 1;
while(!q.isEmpty()) {
int[] now = q.poll();
for (int k = 0; k < 4; k++) {
int nr = now[0] + dir[k][0];
int nc = now[1] + dir[k][1];
if(nr<0||nc<0||nr>=n||nc>=n) continue;
if(road[nr][nc]) continue;
if(trace[nr][nc]>0) continue;
q.add(new int[] {nr,nc});
trace[nr][nc] = trace[now[0]][now[1]] + 1;
}
}
int min = Integer.MAX_VALUE, move_r = -1, move_c = -1;
for (int i = 0; i < 4; i++) {
int nr = r + dir[i][0];
int nc = c + dir[i][1];
if(nr<0||nc<0||nr>=n||nc>=n) continue;
if(trace[nr][nc]==0) continue;
if(trace[nr][nc] >= min) continue;
min = trace[nr][nc];
move_r = nr;
move_c = nc;
}
r = move_r;
c = move_c;
}
}
public static void main(String[] args) throws IOException {
input();
int t = 0;
while(true) {
t++;
int move_num = Math.min(t-1, m);
for (int i = 1; i <= move_num; i++) {
if(arrive[i]) continue;
person now = people[i];
// 1. 1칸 움직이기
now.move();
// 2. 도착했다면 표시해놓기
if(now.r == now.target_r && now.c == now.target_c) {
arrive[i] = true;
}
}
// 2. 도착했다면 멈춤
for (int i = 1; i <= m; i++) {
if(arrive[i]) {
road[people[i].r][people[i].c] = true;
}
}
// 3. t 사람은 베이스캠프 들어가기
if(t<=m) {
person now = people[t];
now.goBase();
}
boolean flag = true;
for (int i = 1; i <= m; i++) {
if(!arrive[i]) {
flag = false;
break;
}
}
if(flag) break;
}
System.out.println(t);
}
private static void input() throws IOException {
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
people = new person[m+1];
arrive = new boolean[m+1];
road = new boolean[n][n];
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
int now = Integer.parseInt(st.nextToken());
if(now==1) bases.add(new int[] {i,j});
}
}
for (int i = 1; i <= m; i++) {
st = new StringTokenizer(br.readLine());
int r = Integer.parseInt(st.nextToken()) - 1;
int c = Integer.parseInt(st.nextToken()) - 1;
people[i] = new person(-1, -1, r, c);
}
}
}
'알고리즘, 자료구조 > 코드트리' 카테고리의 다른 글
[코드트리] 메이즈 러너(JAVA) (0) | 2024.04.12 |
---|---|
[코드트리] 산타의 선물 공장 2(JAVA) (0) | 2024.04.10 |
[코드트리] 산타의 선물 공장(JAVA) (0) | 2024.04.09 |
[코드트리] 싸움땅(JAVA) (0) | 2024.04.08 |
[코드트리] Sam의 피자학교(JAVA) (1) | 2024.04.07 |