ABC121 C - Energy Drink Collectorをstd::pairを使って解く

C++STLにはstd::pairという関数が用意されている。
2つの値の組を表し、使い方も単純で

pair<値1の型, 値2の型> 変数名;

で宣言して

make_pair(値1, 値2);

を使って値を突っ込んでいくだけだ。

いろいろな場面で活用できるのだが、先日AtCoderの過去問を解いているとき、「配列Aをキーとして配列Bをソートする」という場面に遭遇した。
つまり、配列Aを降順(昇順)にソートしたとき、ソート結果に基づいて配列Bも並び替えたい、というものだ。

この「過去問」とは、以下の問題だ。
いくつか解放が考えられるが、今回は上記で示したpair関数を用いて解く。
atcoder.jp
問題を要約すると「ある個数Mのエナジードリンクを手に入れたとき、エナジードリンクの価格の合計の最低値を求めよ」となる。

回答は以下。

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

int main(){
    int N, M;
    cin >> N >> M;
    vector<long long> A(N), B(N);
    vector<pair<long long, long long>> p(N);
    for(int i = 0; i < N; ++i) {
        cin >> A[i] >> B[i];
        p[i] = make_pair(A[i], B[i]);
    }

    sort(p.begin(), p.end());

    long long cnt = 0;
    long long mon = 0;
    for(int i = 0; i < N; ++i) {
        if(cnt + p[i].second <= M) {
            mon += p[i].first * p[i].second;
            cnt += p[i].second;
        } else if(cnt + p[i].second > M) {
            while(cnt < M) {
                cnt++;
                mon += p[i].first;
            }
        }

        if(cnt == M) {
            break;
        }
    }

    cout << mon << endl;
}

まず、この部分で標準入力を行っているが、同時にpair型配列に受け取った値A, Bを突っ込んでいる。

    vector<long long> A(N), B(N);
    vector<pair<long long, long long>> p(N);
    for(int i = 0; i < N; ++i) {
        cin >> A[i] >> B[i];
        p[i] = make_pair(A[i], B[i]);
    }

その受け取った値を持つpを、Aをキーにソートする。同じくSTLのsortを用いれば良い。

sort(p.begin(), p.end());

あとは0番目から順番に価格を計算し、変数に突っ込んでいけばよい。

300点問題の中では簡単な部類だが、慣れていないと手が止まる。