문제링크

  º  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;
}
cs

 

'알고리즘 > BOJ' 카테고리의 다른 글

백준 2805번 나무 자르기  (0) 2020.07.09
백준 1654번 랜선 자르기  (0) 2020.07.08
백준 11651번 좌표 정렬하기 2  (0) 2020.07.08
백준 13397번 구간 나누기 2  (0) 2020.07.08
백준 1939번 중량제한  (0) 2020.07.08

문제링크

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

사용 알고리즘

  º  이분탐색

 

시간복잡도

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

 

풀이

 

N개의 나무들이 주어질때 상근이가 나무를 M미터 챙겨서 가려고 합니다. 나무를 절단하는 높이가 H라고 할때 H보다 높은 부분 즉 나무의 높이 - H만큼의 길이가 한 나무에서 자르는 나무의 길이일때 이걸 합쳐서 M미터를 만들어주면 됩니다.

문제해결을 위해선 H의 높이를 계속해서 주어진 입력값에 대해 적용하여 잘라줘야하는데 나무의 높이로 주어질 수 있는 최대값이 10억입니다. 그래서 이분탐색으로 자를 나무의 높이를 탐색합니다. 최대 $\mathcal{O}(log(10^{10}))$ = 10d의 시간소모.

 탐색을 진행하며 동시에 나무를 잘라서 M미터가 되는지 검사해주는데 지금 자르는 높이보다 작은 나무는 자른 높이를 더해주면 안됩니다. (당연한 얘기같지만 저는 그래서 답이 다르게 나오길래 뭐지했습니다.) 어찌됐든 그래서 M미터 이상이고 지금 정답으로 설정한 높이보다 높으면 갱신해줍니다. 최댓값을 찾아야하니까.

 

소스코드

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
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL), cout.tie(NULL);
    int n;
    long long m,max_t=0;
    vector <long long> v;
    cin >> n >> m;
    v.resize(n);
    for (int i = 0; i < n; i++)
    {
        cin >> v[i];
        if (v[i] > max_t)
            max_t = v[i]; // 가장 큰 키의 나무를 찾아준다.
    }
    long long mid,left = 0, right = max_t, result, ans = 0;
    while (left <= right)
    {
        mid = (left + right) / 2;
        result = 0;
        for (int i = 0; i < n; i++)
        {
            if(mid <v[i]) // 자르는 길이보다 나무가 클때만 잘라준다.
                result += (v[i] - mid);
        }
        if (result >= m)
        {
            left = mid + 1;
            if (mid > ans)
                ans = mid;
        }
        else
            right = mid - 1;
    }
    cout << ans;
    return 0;
}
cs

'알고리즘 > BOJ' 카테고리의 다른 글

백준 2110번 공유기 설치  (0) 2020.07.09
백준 1654번 랜선 자르기  (0) 2020.07.08
백준 11651번 좌표 정렬하기 2  (0) 2020.07.08
백준 13397번 구간 나누기 2  (0) 2020.07.08
백준 1939번 중량제한  (0) 2020.07.08

오늘 한일

· 알고리즘 문제 푼거 풀이 3개 블로그에 등록

  - 백준 11651번 좌표 정렬하기2

  - 백준 13397번 구간 나누기2

  - 백준 1939번 중량제한

 

블로그를 개같이 운영하고 있지만 블로그를 하면서 느낀점은 글로 남기려고 내용을 정리하고 써서 기록하는게 생각보다 도움이 많이된다는점이다.

 

알고리즘만이 아니라 이제 전문개발 분야를 결정하여 공부하는 것에 필요성을 느꼈다. 생각해보면 지금 내가 어느쪽의 개발을 한다하고 말할 수 있는 것이 하나도 없다. 급한 불은 껐으니 이제 다시 열심히 할 시간이 왔다.

 

'TIL > TIL' 카테고리의 다른 글

20200626_TIL  (0) 2020.06.27
20200616_TIL  (0) 2020.06.17
20200615_TIL  (0) 2020.06.16
20200614_TIL  (0) 2020.06.15
20200614_TIL시작  (0) 2020.06.14

+ Recent posts