ぬるぬるの競プロ日記

コードをぬるぬる書きたいです。

AtCoder Beginner Contest 127 D - Integer Cards

考えたこと:

・愚直解として以下のようなものがある。

 

vectorを1つ用意する。(初めにAi(i=1~N)を入れておく。)

 

各jに対して、vectorにBj枚、Cjを入れる。

 

vectorをsortする。

 

大きい方からN枚とる。

 

このN枚は明らかに最大値をとり、このようなN枚は明らかに構成できる。

 

・問題点

最大でpush_backをB_MAX*M=10^10回することになる。

間に合わない。

 

解決策

バケットソートをmapですることにする。

・普通の配列ですると、MLEする。

 

実装

#include <bits/stdc++.h>
using namespace std;
#define int long long

signed main() {
  int N, M;
  cin >> N >> M;
  map<int, int> mp;
  for (int i = 0; i < N; i++) {
    int a;
    cin >> a;
    mp[-a]++;
  }

  for (int i = 0; i < M; i++) {
    int b, c;
    cin >> b >> c;
    mp[-c] += b;
  }

  int ans = 0, cont = 0;
  for (auto x : mp) {

    if (cont + x.second >= N) {
      ans += (N - cont) * x.first * -1;
      break;
    }

    ans += x.second * x.first * -1;
    cont += x.second;
  }

  cout << ans << endl;
  return 0;
}

 

注意点:

カードの整数値にー1を掛けて大きい方から取り出しています。

(mapで範囲forをすると小さい方から取り出されるため。)

 

感想:

少し雑な解説になってしまいました。すみません。

感想としては、もう少し早く解けたかなと言う感じです。