けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

AtCoder ABC 308 B - Default Price (6Q, 灰色, 200 点)

回転寿司を題材にした、とても教育的な面白い問題!

問題概要

高橋君は料理を  N 皿分食べた。皿  i の色は文字列  C_{i} であった。

また、料理の価格は皿の色と対応し、各  i=1, \dots, M について、色が文字列  D_{i} の皿の料理は一皿  P_{i} 円である。

また、 D_{1}, \dots, D_{M} のいずれとも異なる色の皿の寿司は一皿  P_{0} 円である。

高橋君が食べた料理の価格の総和を求めよ。

制約

  •  1 \le N, M \le 100

考えたこと

C++ であれば連想配列 map、Python であれば辞書型 dict が使える練習問題!

次の連想配列を準備しよう。


ma[s] ← 色が文字列  s であるような、皿に乗っている料理の価格


これがあれば、高橋君の食べた各皿の価格が求められる。なお、連想配列にキー (添字のこと) が  s であるものが含まれているかどうかは、C++ の map であれば

if (ma.count(s)) {

}

によって判定できる。

コード

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

int main() {
    int N, M;
    cin >> N >> M;
    vector<string> C(N), D(M);
    vector<long long> P(M + 1);
    for (int i = 0; i < N; ++i) cin >> C[i];
    for (int i = 0; i < M; ++i) cin >> D[i];
    for (int i = 0; i < M + 1; ++i) cin >> P[i];
    
    // 色 -> 価格の対応 map を作る
    map<string, long long> ma;
    for (int i = 0; i < M; ++i) ma[D[i]] = P[i + 1];
    
    // 集計する
    long long res = 0;
    for (int i = 0; i < N; ++i) {
        if (ma.count(C[i])) {
            // 色 C[i] の皿の価格が決まっているとき
            res += ma[C[i]];
        } else {
            // 色 C[i] の皿の価格が決まっていないとき
            res += P[0];
        }
    }
    cout << res << endl;
}