문제링크

  º  https://www.acmicpc.net/problem/2110

사용 알고리즘

  º  이분탐색

 

시간복잡도

  º  $\mathcal{O}(Nlog(10^{10}))$

 

풀이

 

문제에서의 설명이 애매하게 느껴지는데 공유기를 설치한다는 의미는 연속하는 점들을 묶어주는 것과 같은 의미라고 보면 됩니다. 즉, 그룹을 만들어주는 것인데 그룹간의 간격의 최대길이를 지정해 놓고 그 간격으로 최대한의 그룹을 만들어서 묶어주면 그룹이 C개 이상이면 문제를 해결할 수 있습니다.

 

최대길이를 시작점과 끝점의 거리차로 해서 이분탐색을 시작하여 매 탐색시 그룹간격 최대길이로 그룹을 만들어주는 로직을 해줍니다.

그 로직은 전 점의 좌표와 현 점의 좌표의 거리차를 그룹간격 최대길이를 mid라 할때 mid 이상인지 검사해줍니다. mid미만의 값이면 한 공유기에 넣어도 최대길이를 초과할 일이 없기 같은 공유기에 넣어주고, 아니면 새 그룹으로 시작해줍니다.

따라서 탐색은 최대로 나올 수 있는 좌표 10억과 1의 차이인 $\mathcal{O}(log(10^{10}))$=10

매 탐색시 $\mathcal{O}(N)$의 시간소모. 최종적으로 둘을 곱해줍니다.

 

소스코드

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
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL), cout.tie(NULL);
    int n,c;
    vector <long long> v;
    cin >> n >> c;
    v.resize(n);
    for (int i = 0; i < n; i++)
        cin >> v[i];
    sort(v.begin(), v.end());
    int prev,result,ans=0,mid, left = 1, right = v[n - 1]-v[0]; // 오른쪽 최대범위 시작점과 끝점의 거리차
    while (left <= right)
    {
        mid = (left + right) / 2;
        result = 1;
        prev = v[0];
        for (int i = 1; i < n; i++)
        {
            if (v[i] - prev >= mid) // 현재 설정한 최대거리 이상이면 공유기를 하나더추가해줌
            {
                result += 1;
                prev = v[i];
            }
        }
        if (result >= c) // 공유기 개수가 C이상이면 정답보다 큰지 비교
        {
            left = mid + 1;
            if (mid > ans)
                ans = mid;
        }
        else
            right = mid - 1;
    }
    cout << ans;
    return 0;
}
Colored by Color Scripter
cs

 

'Algorithm > boj' 카테고리의 다른 글

백준 1939번 중량제한  (0) 2021.10.24
백준 2805번 나무 자르기  (0) 2021.10.24
백준 14890번 경사로  (0) 2019.11.11
백준 14503 로봇 청소기  (0) 2019.11.11
백준 15662번 톱니바퀴 (2)  (0) 2019.11.10

+ Recent posts