【今日のゆるふわ出張版】 atcoderのbeginner contest 64に殴りこんでみた話

ponanzaチームがPFNの精鋭を加えてから暫く。競技プログラミング勢をもっとコンピュータ将棋に引き込みたい、それならまずはコンピュータ将棋勢が競技プログラミングに手を出してみるべきだということで、将棋ソフトレーティングサイトの自称上位ランカー(笑)である"qhapaq"の中の人が敢えて爆死しに行ってきました。

 

問題は此方からどうぞ:

AtCoder Beginner Contest 064 - AtCoder Beginner Contest 064 | AtCoder

 

結果概略:

全問正解はできましたが、問題の読み間違いや調子こいて変なコードを書いたせいでコンパイルエラーを喰らったりして順位的にはなんとも微妙なものになってしまいました。

f:id:qhapaq:20170610230141p:plain

 

【得られた知見1:思考停止も立派な戦術】

問1:

1-9の数字が3つの標準入力で与えられ、その3つをつなげて作られた3桁の数字が4の倍数か判別する問題。

例: 1 6 8 が与えられた場合、168は4の倍数なのでYES、4 0 1が与えられた場合401は4の倍数ではないのでNO。

少なくとも百の位は数字が何であっても影響はありません。十の位もmod4では2, 0, 2, 0を繰り返すだけです。故に、十の位の数☓2 + 一の位のmod 4をとることで高速に判別が可能です。.....が、そんなことを考えないほうが問題は早く解けます。計算条件的には1 * 100 + 6 * 10 + 8のmod 4を計算するので十分です。

変な数理に目移りして暫く手が止まりましたが、ぐっとこらえて100の位だけ無視して10の位☓10+1の位のmod 4を計算させて撃破。

 

【得られた知見2:言語の仕様に精通しよう】

問2:

1次元空間上のN個の家の位置が標準入力で与えられ、好きな場所からスタートして全ての家を通る際の移動距離の総和を計算する問題。

家の座標をsortして、最大値と最小値を計算すればいいので、vectorのsortでOKと思ったのですが、ここでまさかのコンパイルエラー。どうもvectorのsortにはalgorithmが必要だったようです。

コンパイルを通してsubmitしたら、ジャッジはまさかのエラー。なぜだなぜだとコードをいじくり回した結果、悪ふざけでreturnの値を-1にしていたのが不味かったことが発覚。コードに必要のない /*  let's try computer shogi ! */という遺言を残す暇はなかったようです。

 

【得られた知見3:問題文をよく読み、必要なら質問をしよう】

問3:

競技プログラミングにおけるN人のプレイヤーのN個のレートが与えられ、プレイヤー全体が作る色の種類の最大/最小値を求める問題。各プレイヤーの色はレートによって定められているが、一定の値を超えると"好きな色"にできるとのこと(atcoderの仕様かな?)。

所謂場合分けをしっかりやらねばならない問題。N-M人のレートの色が固定されてる人が作る色の種類は固定(Aとする)であり、M人の好きな色を設定できる勢が作る色の種類は1-M種類であるため、答えは最小値はmax(A,1)、最大値はA+Mです(ただし、参加者が0人の場合は0を返す必要があります!)

が、"好きな色"の定義が本当に好きな色(ビリジアンとかも選べる)なのか、色固定組が持っている色の中から好きな色を選べるのかが解らず、誤った解釈(=後者の解釈)をしてしまったため、物凄く時間を消費しました。よく見れば入力例で色固定組の色以外の色が出てきていたのですが、30分以上費やして、漸く問題の解釈ミスの可能性に気づき、質問掲示板で同様の質問と回答を見つけ、解釈ミスに気付いて撃破。

# 序に、レート色の境界線の以下と未満も読み違えてたのでメッチャ時間使いましたorz

 

【得られた知見4:消費時間のバランスと問題の解ける解けないの判断を正確にやろう】

問4:

"("と")"からなる文字列に"("と")"を付け足してカッコが閉じた文字列を作る問題。stringの使い方がよく解らず、延々とコンパイルエラーを出し続けましたが、アルゴリズム自体を偶然一発で導出できたのもあり、なんとか10分以内に通すことが出来ました。今回は問3も解けた+問4との相性が良かったからあまり気にする必要はないですが、もう少し時間がタイトな大会などでは、早い段階で問3に見切りをつけるべきだったろうなと反省してます。

 

【得られた知見5:競技プログラミング強い人は凄い】

アルゴリズムを思いつくスキルもさることながら、高い文章整理スキル(日本語や英語の問題を正しく理解するスキル)やコンパイルエラーを出さないスキルの必要性を強く感じました。

私自身はその手の作業は正直あんまり好きではなく、得意でもないので今まで競技プログラミングを避けてきましたが、自分を鍛える意味で今後も続けてみたいと思います。

 

競技プログラミングは楽しいから、将棋勢ももっと殴りこみましょう。あと逆もしかり。