nekoTheShadow’s diary

IT業界の片隅でひっそり生きるシステムエンジニアです(´・ω・`)

AtCoder Beginner Contest 170 - C問題 "Forbidden List" の解説

自分は参加していなかったのですが、先日開催されたAtCoder Beginner Contest 170C問題"Forbidden List"の解説がなかなか不親切ということで、自分のTwitterのタイムラインでは少し話題になっていました(→PDF)。解説の内容は「ある1点だけ注意すれば、あとは問題文の通りに実装するだけ。詳しい内容は省略! 実質はB問題レベルだよ」というもので、とくに「B問題レベル」というのを煽りの一種にとらえた人もいるようでした。個人的にはそこまで攻撃的なニュアンスには思えなかったものの、Beginner向けを打ち出しているコンテストにしてはやや不親切かなと。そもそもC問題が解けないから、解説を読んで理解しようとしているわけです。にもかかわらず、そこで解説が省略されて困っちゃうという人はいると思います。

ちなみにYouTubeの解説動画ではC問題についてもわかりやすく説明されていたので、ちゃんと理解したい人はそちらを視聴しましょう(→動画)。ただ動画を再生できる環境がなかったり、聴覚障害などの影響で音声解説だと困ったりと、各々事情があると思うので、わたしなりに解説を書いてみたいと思います。自分自身も競技プログラミングで遊ぶなかで、さまざまな人が書いたBlog記事にずいぶんと助けられてきたので、その恩返しというか恩送りの気持ちもあります。


atcoder.jp

以下の順番に調べていって、初めて配列Pに含まれていないものが答えになります。

  •  X
  •  X-1
  •  X+1
  •  X-2
  •  X+2
  •  X-3
  •  X+3
  •  X-4
  •  X+4
  • (以下同じように続く)

たとえば入力例1の場合 ( X=6, P=[4,7,10,6,5])は以下のようになるはずです。

  •  X=6Pに含まれる
  •  X-1=6-1=5Pに含まれる
  •  X+1=6+1=7Pに含まれる
  •  X-2=6-2=4Pに含まれる
  •  X+2=6+2=8Pに含まれないのでこれが答え

たとえば X+100000000000000000とかが答えだった場合、 X→X-1→X+1...とひとつづつチェックしていくと、さすがにTLEしてしまうのでは……と不安になるかもしれませんが、実はその心配はありません。問題の制約を見ると、X1以上100以下、Pの長さは1以上100以下で、その中身も1以上100以下であることが保証されています。この制約下でやばそうなケースを考えてみると、以下のようなものが思いつきます。

  •  X=50
  •  P=[2,3,4,...,98,99,100]

これを上記に示した順番で調べていくと、実は98回程度で答えが見つかることが分かります。

  • (01)  X=50Pに含まれる
  • (02)  X-1=49Pに含まれる
  • (03)  X+1=51Pに含まれる
  • (04)  X-2=48Pに含まれる
  • (05)  X+2=52Pに含まれる
  • (中略)
  • (94)  X-47=3Pに含まれる
  • (95)  X+47=97Pに含まれる
  • (96)  X-48=2Pに含まれる
  • (97)  X+48=98Pに含まれる
  • (98)  X-49=1Pに含まれないのでこれが答え

何やら凝ったアルゴリズムを実装しないといけないように思えますが、実は上記のような単純な手順でも100回程度の探索で答えにはたどり着いてしまうので、心配せずにSubmitしちゃいましょう。わたしの提出コード(Python3)は以下の通りです。

atcoder.jp