https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5-BEE6AK0DFAVl
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
public class Solution {
public static int T, N, ans = 0, hNum;
public static int[][] stairs;
public static int[] arr;
public static List<Hu> list;
public static class Hu {
int x, y, dis0, dis1, dist, end;
public Hu(int x, int y, int dis0, int dis1, int dist, int end) {
super();
this.x = x;
this.y = y;
this.dis0 = dis0;
this.dis1 = dis1;
this.dist = dist;
this.end = end;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
T = Integer.parseInt(br.readLine());
for (int tc = 1; tc <= T; tc++) {
// 1. 입력받기
N = Integer.parseInt(br.readLine());
ans = 100;
hNum = 0;
// 1-1. map을 입력받으며 human과 stairs 위치 받기
list = new ArrayList<>();
stairs = new int[2][3];
int cnt = 0;
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
int a = Integer.parseInt(st.nextToken());
if (a == 1) {
list.add(new Hu(i, j, 0, 0, 0, 0));
hNum++;
} else if (a > 1) {
stairs[cnt][0] = i;
stairs[cnt][1] = j;
stairs[cnt++][2] = a;
}
}
}
for (int i = 0; i < list.size(); i++) {
Hu cur = list.get(i);
int ox = Math.abs(cur.x - stairs[0][0]);
int oy = Math.abs(cur.y - stairs[0][1]);
int tx = Math.abs(cur.x - stairs[1][0]);
int ty = Math.abs(cur.y - stairs[1][1]);
cur.dis0 = ox + oy; // 0번계단 까지의 길이
cur.dis1 = tx + ty; // 1번계단 까지의 길이
}
// 2. 무슨 계단을 내려갈 것인지 부분집합 구해주기
arr = new int[hNum];
dfs(0);
// 2-3. dp에서 가장 마지막에 나가는 값을 갱신 후 ans 와 비교 가장 작은 값 출력
System.out.println("#" + tc + " " + ans);
}
}
public static void dfs(int depth) {
if (depth == hNum) {
int min = 0;
List<Hu> zero = new LinkedList<>();
List<Hu> one = new LinkedList<>();
for (int i = 0; i < hNum; i++) {
Hu cur = list.get(i);
// 거리 + 계단의 길이 구하기
if (arr[i] == 0) {
cur.dist = cur.dis0;
cur.end = cur.dist + stairs[0][2] + 1;
zero.add(cur);
} else {
cur.dist = cur.dis1;
cur.end = cur.dist + stairs[1][2] + 1;
one.add(cur);
}
}
zero.sort((o1, o2) -> Integer.compare(o1.dist, o2.dist));
one.sort((o1, o2) -> Integer.compare(o1.dist, o2.dist));
int cnt0 = 0, cnt1 = 0;
int[] ze, on;
ze = new int[10];
on = new int[10];
for (Hu d : zero) {
if (cnt0 < 3) {
ze[cnt0++] = d.end;
} else {
if (ze[cnt0 - 3] > d.dist) {
ze[cnt0] = ze[cnt0 - 3] + stairs[0][2];
} else {
ze[cnt0] = d.end;
}
cnt0++;
}
}
for (Hu d : one) {
if (cnt1 < 3) {
on[cnt1++] = d.end;
} else {
if (on[cnt1 - 3] > d.dist) {
on[cnt1] = on[cnt1 - 3] + stairs[1][2];
} else {
on[cnt1] = d.end;
}
cnt1++;
}
}
if (zero.size() == 0) {
cnt1--;
} else if (one.size() == 0) {
cnt0--;
} else {
cnt1--;
cnt0--;
}
int z = ze[cnt0];
int o = on[cnt1];
min = Math.max(z, o);
// 마지막 사람의 나가는 시간 계산
if (ans > min) {
ans = min;
}
return;
}
arr[depth] = 0; // 0번 계단 선택
dfs(depth + 1);
arr[depth] = 1; // 1번 계단 선택
dfs(depth + 1);
}
}'코딩테스트 > JAVA' 카테고리의 다른 글
| [백준 JAVA] 20187번: 종이접기 (0) | 2024.09.02 |
|---|---|
| [백준 JAVA] 15683번: 감시 (0) | 2024.08.29 |
| [SWEA JAVA] 1251. [S/W 문제해결 응용] 4일차 - 하나로 (0) | 2024.08.29 |
| [SWEA JAVA] 3124. 최소 스패닝 트리 (0) | 2024.08.29 |
| [SWEA JAVA] 7465. 창용 마을 무리의 개수 (4) | 2024.08.28 |