forked from GreatAlgorithm-Study/AlgorithmStudy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSB_60062.java
More file actions
62 lines (55 loc) · 3.23 KB
/
SB_60062.java
File metadata and controls
62 lines (55 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class SB_60062 {
static int N;
static int[] Dist, expandWeak;
static int M;
static int ans = Integer.MAX_VALUE;;
private static void check(int[] take) {
for (int start = 0; start < expandWeak.length / 2; start++) { // 취약 지점의 시작위치(인덱스)는 기존 배열의 범위 내 존재
int cnt = 0; // 커버한 친구 수
int pos = expandWeak[start]; // 현재 친구가 커버 시작할 위치
for (int fd : take) {
cnt++;
pos += Dist[fd]; // 현재 친구가 마지막으로 커버한 위치 (현재 친구가 커버할 수 있는 최대 거리)
// 현재 친구로 모든 지점 다 커버할 경우
if (pos >= expandWeak[start + expandWeak.length / 2 - 1]) { // 시작 위치를 기점으로 취약구간의 길이만큼 조사(=모든 취약 지점 조사) 시
ans = Math.min(ans, cnt); // 최소값 갱신
return;
}
// 다음 친구 추가해야할 경우
int nxtStart = start + 1; // 다음 취약 지점의 인덱스 (expandWeak에서 커버되지 않은 첫번째 취약지점 가르키기)
while (nxtStart < expandWeak.length / 2 && expandWeak[nxtStart] <= pos) { // 취약 지점의 인덱스가 기존 배열의 인덱스에 위치하고, 이미 이전 친구가 커버했다면
nxtStart++; // 포인터 이동하며 다음 취약 시작 지점 찾기
}
start = nxtStart - 1; // 다음 친구가 커버 시작할 시작 지점 설정.
}
}
}
private static void perm(int depth, int cnt, boolean[] visited, int[] take) { // 현재 시작점, 친구 수
if (depth == cnt) {
check(take);
return;
}
for (int i = 0; i < M; i++) {
if (visited[i]) continue; // 이미 방문한 친구는 패쓰
take[depth] = i; // 데려갈 수 있는 경우 데려가고
visited[i] = true;
perm(depth + 1, cnt, visited, take); // 데려간 친구로 dfs 마져 수행
visited[i] = false; // 다시 돌려놓기
}
}
public static int solution(int n, int[] weak, int[] dist) {
N = n;
Dist = dist;
M = dist.length;
// 기존 배열 확장 (반시계도 일자로 진행하기 위함)
expandWeak = new int[weak.length * 2];
for (int i = 0; i < weak.length * 2; i++) {
if (i < weak.length) expandWeak[i] = weak[i];
else expandWeak[i] = weak[i%weak.length] + N;
}
for (int i = 1; i < M+1; i++) { // 데러갈 친구 수
perm(0, i, new boolean[M], new int[i]); // 1부터 M까지 경우에 대한 순열 구하기
}
return ans == Integer.MAX_VALUE ? -1 : ans;
}
}