AtCoder Beginner Contest 191のきろく

D問題が通せなかった...

A - Vanishing Pitch (100点)

TV \leq D \leq SV であるかどうかを判定します。前回のAのWAで焦ってしまった経験からサンプル通してから提出しているので少し遅いです。

B - Remove It (200点)

問題文通りに実装します。X と等しい要素をスキップしながら出力でもいいのですが、空白が入ってしまうので避けました*1

C - Digital Graffiti (300点)

(S_{i,j},\,S_{i-1,j},\,S_{i,j-1}) = (#,\,#,\,#)(S_{i,j},\,S_{i-1,j},\,S_{i,j+1}) = (#,\,#,\,#)(S_{i,j},\,S_{i+1,j},\,S_{i,j-1}) = (#,\,#,\,#)(S_{i,j},\,S_{i+1,j},\,S_{i,j+1}) = (#,\,#,\,#)である (i,\,j) の組の延べ個数を N とします。N は延べ個数なので上の条件を2つ満たしているときは2組、3つなら3組、4つなら4組として扱います。この N は内角が 90^\circの角の数です。N は最小で 4 ですが、これは四角形の時になります。そして、N1 増えると内角が 90^\circの角と内角が 270^\circの角がそれぞれ 1 個増え、辺の数は 2 本増えます。なので答えは 4 + 2(N-4) = 2N - 4 となります。

D - Circle Lattice Points (400点)

(x,\,y) が円の内部または周上にある条件は (x - X)^2 - (y - Y)^2 \leq R^2 です。格子点の個数なので、直線 x=c 上の条件を満たす格子点の個数を求めて c を円と共有点をもつ範囲で動かして合計をとればいいです。X - R \leq c \leq X + R であり、c を1つ決めたとき、R^2 - (c - X)^2 \geq 0 であり、$$ \begin{align}
& (y-Y)^2 \leq R^2 - (c-X)^2 \\
\Longleftrightarrow\ & |y-Y| \leq \sqrt{R^2 - (c - X)^2} \\
\Longleftrightarrow\ & Y - \sqrt{R^2 - (c-X)^2} \leq y \leq Y + \sqrt{R^2 - (c-X)^2}
\end{align} $$ となるので、この範囲で (\text{最大の整数} - \text{最小の整数} +1) が直線 x = c 上の格子点の個数です。
コンピュータで計算させる際は小数で計算させると誤差が出てくるので、全体に 10^4 をかけてやることで整数にして計算を行います。
ここで雑に普通に型変換でええやろ、ってやってWAのまま終わってしまいました。普通の型変換は切り捨てなのですが、それだとまずいケースがあり、round関数を挟む必要があったようです。こちらのコードで例えば99999.9999がそのケースの一例なのが分かります。
また、y の範囲を求める時、ルートをとる関係で小数型が出てくるので、区間の両端の所は少しだけ幅を確認してみてみるといいでしょう。

E - Come Back Quickly (500点)

i を出発点とする正しい散歩経路は、自己ループか i へ続く道がある町まで最短距離で行き、そこから i へ帰ってくる経路の最短なもの、のどちらかであるのでDijkstra法などを用いて計算することができます。

F - GCD or MIN (600点): 未提出

未だ解けてないので、何も書けません。

結果、感想

f:id:Flkanjin:20210207003456p:plain
やっぱり、D問題が通せなかったのが悔しいですね。どっか間違った計算をさせているんじゃないかと思って、色々いじっていたのですが、計算ではなく型変換のやり方がまずかったというわけで、そこを修正したらすぐにACになりました。言われてみればそりゃ、常に0方向への丸めにするのはまずいのですが、コンテスト中はそこまで気が回っていませんでした。

*1:最近のAtCoderは余計が空白や改行があってもよいことにはなっているのですが