実行時間制限: 2 sec / メモリ制限: 1024 MB / Difficulty: 422
問題概要
から までの番号が付けられた 人の選手がいる。初めは全員0点である。今から 秒後に選手 の得点が 点増加する。今から 秒後の時点における、 人の選手の得点の種類をそれぞれ出力せよ。
制約
- 入力はすべて整数
考察
出力時に問われているのは「選手たちの得点の種類」だから、各時刻で、ある得点に対して「その得点を何人が持っているのか」が分かればよい。したがって、得点をkey
、その得点を持つ選手の人数をvalue
とする連想配列を作成する。C++ではmap
型が使えるだろう。ここではmap<long long, long long>
型の変数として、mp
を用いた。
また、各選手の得点を記録する配列も必要。これは得点の更新の際に必要となる。ここではvector<long long>
型の変数として、scores
を用いた。処理は以下のようになる。
- 初期化時は
mp[0] = N
で行う。
- 秒後に選手 の得点が 点増加するとする。まず、得点 ] の人数が一人減るのだから、
mp[scores[A_i]]--;
である。このとき、mp[scores[A_i]] = 0
となった場合は、その要素を削除しなければならないことに注意する。残したままだと、出力時に余計に加算されてしまう。
- 次に、選手 の得点に 点を追加する。
scores[A_i] += B_i
で良いだろう。
- 最後に、得点の種類を出力する。これは
mp.size()
に対応する。
以上の説明は1-indexed
で書いたが、コードでは0-indexed
としている。
コード
#include <bits/stdc++.h> using namespace std; #define rep(i, start, end) for (ll i = (start); i < (ll)(end); i++) using ll = long long; // ======================================== // int main() { int N, T; cin >> N >> T; vector<ll> scores(N, 0); map<ll, ll> mp; mp[0] = N; rep(i, 0, T) { int A, B; cin >> A >> B; mp[scores[A - 1]]--; if (mp[scores[A - 1]] == 0) mp.erase(scores[A - 1]); scores[A - 1] += B; mp[scores[A - 1]]++; cout << mp.size() << endl; } }
実装時間: 45分