ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1283-D, *1800
    코드포스 2021. 9. 16. 00:53
     

    Problem - D - Codeforces

     

    codeforces.com

    문제

    • $n(1 \leq n \leq 2\cdot 10^{5})$개의 나무가 수직선 위의 서로다른 $x_{i} \in \mathbb{Z}$에 있다
    • $m(1 \leq m \leq 2\cdot 10^{5})$명의 사람의 위치 $y_{i} \in \mathbb{Z}$는 다음 조건을 만족해야 한다 
      1. 나무가 있는 정수좌표에는 사람이 있으면 안된다
      2. 한 좌표에는 두명 이상이 있으면 안된다
    • 어떤 사람 $y_{i}$의 인접한 나무와의 거리를 $d_{i}$라 할때, $d_{i} = \overset{n}{\underset{j=1}{\text{min}}}|y_{i}-x_{j}|$
      $d_{i}$의 합이 최소가 되도록 사람을 배치할 때의 $\mathrm{Sum(d_{i})}$과 $y_{i}$를 출력하라

     

    $O(nlog\ n)$

    c++

    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
    #include <bits/stdc++.h>
    #define endl "\n"
    #define ooop(i, n) for(int i = 0; i < n; i++)
    #define loop(i, n) for(int i = 1; i <= n; i++)
     
    using namespace std;
    typedef long long ll;
    typedef pair<intint> pii;
    typedef pair<ll, ll> pll;
     
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0), cout.tie(0);
     
        int n, m;
        cin >> n >> m;
     
        vector<int> tree(n);
        for(auto& e: tree) cin >> e;
     
        queue<pair<intint> > q;
        set<int> occupied;
        vector<int> res;
        for(auto coord: tree){
            occupied.insert(coord);
            q.push({coord-11});
            q.push({coord+11});
        }
     
        ll d_sum = 0;
        int cur, dis;
        while(m){
            tie(cur, dis) = q.front(), q.pop();
            if(occupied.find(cur) == occupied.end()){
                d_sum += dis;
                res.emplace_back(cur);
                occupied.insert(cur);
                q.push({cur-1, dis+1});
                q.push({cur+1, dis+1});
                m--;
            }
        }
     
        cout << d_sum << endl;
        for(auto e: res) cout << e << ' ';
     
        return 0;

    ※ sum_d 는 long long 이어야 한다!!

    python3

    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
    import sys
    from collections import deque
    from collections import defaultdict as dd
     
    n, m = map(int, input().split())
    tree = list(map(int, sys.stdin.readline().split()))
    occupied = dd(bool)
    = deque([])
     
    for t in tree:
        occupied[t] = True
        q.append((t-11))
        q.append((t+11))
     
    dist_sum = 0
    res = []
    while m:
        coord, dist = q.popleft()
        if occupied[coord]: continue
        occupied[coord] = True
        res.append(coord)
        dist_sum += dist
        q.append((coord-1, dist+1))
        q.append((coord+1, dist+1))
        m -= 1
     
    print(dist_sum)
    print(*res)cs

     

    참고

     

    안즈와 소소한 취미생활

     

    anz1217.tistory.com

    본 게시물의 코드는 안즈선배님의 도움을 받아 작성한 코드입니다.

    '코드포스' 카테고리의 다른 글

    1604-D, *1600  (0) 2021.10.31
    1283-C, *1500  (0) 2021.09.17
    1560-A, *800  (0) 2021.08.30
    1498-B, *1300  (0) 2021.08.16
    1553-C, *1200  (0) 2021.08.15

    댓글

Designed by Tistory.