답은 알고리즘 뿐이야!

[BOJ 2517] 달리기 본문

알고리즘/백준문제풀이

[BOJ 2517] 달리기

skyde47 2020. 1. 8. 00:15

문제 출처 : https://www.acmicpc.net/problem/2517

 

풀이 :

 

분할정복으로 풀 수 있는 문제입니다.

머지소트를 진행하면서 왼쪽보다 오른쪽이 더 클때 순위를 왼쪽의 남은 숫자 만큼 빼주시면 됩니다.

원리는 우측에 있는 러너가 좌측으로 이동할때 좌측에 남은 숫자만큼 추월을 한다고 생각하시면 됩니다.

 

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
#include<stdio.h>
 
struct num {
    int v, r;
    num(int v, int r) :v(v), r(r) {}
    num() {}
};
int n, t, rank[500000];
num arr[500000], sort[500000];
 
void mergesort(int l, int r) {
    if (l >= r)return;
    int mid = (l + r + 1/ 2;
    int ll = l, rr = mid, cnt = l;
    while (ll < mid&&rr <= r) {
        if (arr[ll].v > arr[rr].v) {
            sort[cnt++= arr[ll++];
        }
        else {
            sort[cnt++= arr[rr];
           rank[arr[rr++].r] -= mid-ll;
        }
    }
    while (ll < mid)sort[cnt++= arr[ll++];
    while (rr <= r)sort[cnt++= arr[rr++];
    for (int i = l; i <= r; i++)arr[i] = sort[i];
}
 
void merge(int l, int r) {
    if (l >= r) return;
    int mid = (l + r + 1/ 2;
    merge(l, mid - 1);
    merge(mid, r);
    mergesort(l, r);
}
 
int main() {
    scanf("%d"&n);
    for (int i = 0; i < n; i++) {
        scanf("%d"&t);
        arr[i] = num(t, i);
        rank[i] = i;
    }
    merge(0, n - 1);
    for (int i = 0; i < n; i++)printf("%d\n", rank[i]+1);
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

 

'알고리즘 > 백준문제풀이' 카테고리의 다른 글

[BOJ 3860] 할로윈 묘지  (0) 2020.01.14
[BOJ 11003] 최솟값 찾기  (0) 2020.01.08
[BOJ 1103] 게임  (0) 2020.01.06
[BOJ 1062] 가르침  (0) 2020.01.06
[BOJ 7453] 합이 0인 네 정수  (0) 2020.01.02
Comments