ARMERIA

Rubyと競技プログラミングの話 AtCoderやCodeforcesの問題解説記事が多め。

AtCoder Beginner Contest 136 D - Gathering Children

D - Gathering Children

私の解法をTwitterに流したらわりと好評だったので記事にまとめておきます。

解法

ある程度動きをシミュレーションしてみると、十分に時間が経った後は全ての子供が RL の2マスで振動するということが分かります。最終状態を求めるためには動きが止まってくれると考えやすいのですが、振動する動きをそのまま扱うと少し面倒です。これを扱いやすくするために、移動2ターンをセットで考えてみることにしましょう。

2ターンをセットで考えると子供の動きは以下の3パターンに分類されます。

  • 自分が R で右隣も R:2ターンで右に2マス動く。
  • 自分が L で左隣も L:2ターンで左に2マス動く。
  • それ以外:振動するので、2ターン単位で見ると動かないとみなせる。

ここで、例えば2マス右に動いた子供が次の2ターンも2マス右に動くことはあり得ます。しかし2マス右に動いた子供が次の2ターンで左に2マス動くことはありません。2マス右に動いた後に左隣にあるのは必ず R なので、2マス左に動く条件を満たさないからです。全く同様の理由で「左2→左2」はあり得ますが「左2→右2」はあり得ません。

よって、右に動く子供と左に動く子供は独立に考えることができます。具体的には、

  • 最初に全てのマスに1人ずつ子供を置いておく。
  • 左端から順番にマスを見ていき、「見ているマスと右隣がともに R」であればそのマスにいる子供を全て2マス右に移動させる。
  • 右端から順番にマスを見ていき、「見ているマスと左隣がともに L」であればそのマスにいる子供を全て2マス左に移動させる。

とすることで答えを求めることができます。移動の総回数が偶数なので、2マス単位の移動を十分な回数繰り返した状態が答えになります。

ACコード

Submission #6691873 - AtCoder Beginner Contest 136