シミュレーションを冷静に実装しよう!
問題概要
マス があって、マス 1 はスタート、マス 2019 はゴールである。 個のコマがあり、それぞれ 番目にマスに置かれている。
次の 回の操作を実行する。
- 回目の操作ではコマ を動かそうとする
- もしコマ の置いてあるマスがゴールマスでない、かつ、その右隣のマスにコマが置かれていないならば、コマ を右隣のマスに動かす
操作の実行後の 個のマスの置かれた番号を答えよ。
制約
考えたこと
問題文で書かれた通りにシミュレーションしましょう。ただし、一つ問題になるのは、次の点でしょう。
コマ を右隣に動かす操作が OK かどうかを判定する
まず、コマ がすでにゴールしているとき( のとき)は動かせません。以降、コマ はゴールしていない場合を考察します。
さて、コマの位置 について、どれだけ操作をしても
という関係性が保たれることに注意しましょう。よって、コマ の右側にあるコマは です。つまり、コマ が動きたい先のマスにいる可能性のあるコマは のみです。このことに注意して、次のように整理できます。
- のとき:コマ の移動先にコマ があるので、コマ は動けない
- のとき:コマ の移動先にはコマがないので、コマ は動ける
これらのことに注意してシミュレーションしましょう。次のように実装できます。
コード
#include <bits/stdc++.h> using namespace std; int main() { int N, M, A; cin >> N; vector<int> X(N); for (int i = 0; i < N; i++) cin >> X[i]; X.push_back(2020); // 番兵 cin >> M; for (int i = 0; i < M; i++) { cin >> A, A--; if (X[A+1] <= X[A] + 1) continue; X[A]++; } for (int i = 0; i < N; ++i) cout << X[i] << endl; }