알고리즘/백준
[Java] 백준 2517 달리기
24시간이모자란
2023. 1. 15. 03:58
문제
https://www.acmicpc.net/problem/2517
2517번: 달리기
첫째 줄에는 선수의 수를 의미하는 정수 N이 주어진다. N은 3 이상 500,000 이하이다. 이후 N개의 줄에는 정수가 한 줄에 하나씩 주어진다. 이 값들은 각 선수들의 평소 실력을 앞에서 달리고 있는
www.acmicpc.net
풀이
현재 위치 i 에서 0..i-1 중에 자신의 실력보다 낮은 개수를 센 다음, 차를 구하는 문제.
분할 정복으로 정렬해서 O(N log N) 풀이하였다.
알고리즘은 다음과 같다.
1. 분할 정복 소트 기법을 사용한다.
2. 두 배열을 병합할때 RIght 배열 원소를 삽입 할때 자기 Left 배열에서 현재숫자보다 낮은 개수를 누적합한다.
3. 자기 자신의 인덱스 - 자신 실력보다 낮은 선수의 숫자 + 1 을 정답 배열에 담는다.
분할 정복이 처음이신 분들은 백준 예제에, 위 알고리즘을 적용한 풀이 사진을 참고하길 바란다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Data {
public int num, idx, low;
Data(int num, int idx, int big){
this.num = num;
this.idx = idx;
this.low = big;
}
}
class Main {
Data[] a, b;
public static void main(String[] args) throws IOException {
Main T = new Main();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int arr[] = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(br.readLine());
}
int ans[] = T.solution(arr);
for(int i = 0 ;i < n ;i++){
ans[i] = i - ans[i] + 1;
}
StringBuilder sb = new StringBuilder();
for(int x : ans)
sb.append(x).append("\n");
System.out.println(sb.toString());
}
public int[] solution(int[] nums) {
int n = nums.length;
a = new Data[n];
b = new Data[n];
for (int i = 0; i < n; i++) {
a[i] = new Data(nums[i], i, 0);
}
devide(0, n - 1);
int[] answer = new int[n];
for (int i = 0; i < n; i++) {
answer[a[i].idx] = a[i].low;
}
return answer;
}
public void devide(int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
devide(left, mid);
devide(mid + 1, right);
int p1 = left;
int p2 = mid + 1;
int p3 = left;
while (p1 < mid + 1 && p2 < right + 1) {
if (a[p1].num > a[p2].num) {
b[p3] = a[p2++];
b[p3++].low += (p1 - left);
} else {
b[p3++] = a[p1++];
}
}
while (p2 < right + 1) {
b[p3] = a[p2++];
b[p3++].low += (p1 - left);
}
while (p1 < mid + 1) b[p3++] = a[p1++];
for (int i = left; i < right + 1; i++) {
a[i] = b[i];//update sorted data
}
}
}
}