알고리즘 문제해결/BOJ

BOJ 23090 난민

havana723 2022. 8. 30. 14:28

https://www.acmicpc.net/problem/23090

 

23090번: 난민

문제의 답을 공백으로 구분하여 \(N\)줄에 걸쳐 출력한다. \(i\)번째 줄에, \(1\)번째 부터 \(i\)번째까지 이주해온 난민들이 정수시설까지 이동하는 거리의 합이 최소가 되도록 하는 정수시설의 \(y\

www.acmicpc.net

 

블로그에 올렸던 쌀 창고 + 중앙값 구하기인 문제입니다.

 

https://havana723.tistory.com/16

 

BOJ 5821 쌀 창고

https://www.acmicpc.net/problem/5821 5821번: 쌀 창고 쌀 창고 이 경우에는 창고의 위치에 대한 여러 개의 최적 위치가 있다: 10 이상 14 이하의 어느 정수 위치에든지 쌀 창고를 둘 수 있다. 위의 그림은 최

blog.havana.moe

https://www.acmicpc.net/problem/2696

 

2696번: 중앙값 구하기

첫째 줄에 테스트 케이스의 개수 T(1 ≤ T ≤ 1,000)가 주어진다. 각 테스트 케이스의 첫째 줄에는 수열의 크기 M(1 ≤ M ≤ 9999, M은 홀수)이 주어지고, 그 다음 줄부터 이 수열의 원소가 차례대로 주

www.acmicpc.net

 

x값의 경우 정수시설의 x축 좌표가 항상 0이므로 고려할 필요 없이 절댓값을 답에 더해주면 됩니다. y값의 경우 쌀 창고와 농구 골대에서 썼던 아이디어를 이용하면 정수시설이 y값들의 중앙값에 있을 때 거리가 최소가 된다는 것을 알 수 있습니다.

 

매 쿼리마다 중앙값을 구하기 위해 중앙값 구하기의 아이디어를 이용하여 우선순위 큐 두 개를 사용해 구합니다. 중앙값을 기준으로 중앙값보다 큰 값을 기록하는 최소 우선순위 큐를 하나, 중앙값을 기준으로 중앙값과 같거나 작은 값을 기록하는 최대 우선순위 큐를 하나 만든 뒤 양 큐의 크기가 같게 유지하면 중앙값을 바로 구할 수 있습니다.

 

아래는 코드입니다.

 

#include <bits/stdc++.h>
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
#define ends ' '
#define int long long

using namespace std;

int T, n;

int32_t main(void) {
  FastIO;
  T = 1;
  //cin >> T;

  while (T--) {
    cin >> n;

    priority_queue<int, vector<int>, greater<int>> big;
    priority_queue<int> small;

    int xsum = 0;
    int ssum = 0;
    int bsum = 0;

    while (n--) {
      int x, y;
      cin >> x >> y;

      int prevm = 0;
      if (!small.empty()) prevm = small.top();

      xsum += abs(x);

      if (big.size() >= small.size()) {
        small.push(y);
        ssum += y;
      }
      else {
        big.push(y);
        bsum += y;
      }

      while (!big.empty() && !small.empty() && big.top() < small.top()) {
        int a = big.top();
        int b = small.top();

        big.pop();
        small.pop();

        big.push(b);
        small.push(a);

        bsum -= a;
        ssum -= b;
        bsum += b;
        ssum += a;
      }


      int nowm = small.top();
      int nowb = big.size();
      int nows = small.size();

      int ans = xsum;
      ans += (nows * nowm) - ssum;
      ans += bsum - (nowb * nowm);

      cout << nowm << ends << ans << endl;
    }
  }

  return 0;
}

'알고리즘 문제해결 > BOJ' 카테고리의 다른 글

BOJ 17308 Getting-Up Syndrome  (0) 2022.09.01
BOJ 25402 트리와 쿼리  (0) 2022.08.31
BOJ 24456 초콜릿 훔쳐 먹기  (0) 2022.08.29
BOJ 24914 Split the SSHS  (0) 2022.08.29
BOJ 2647 검은점과 하얀점  (0) 2022.08.14