競技プログラミング
訓練
青 diff の AC 数が 50 を超えた。自力で解ける気配は無い。
マスター・オブ・場合の数
の §1 を解いた。意外と DP の観点が役立つ。
ABC 335
ABC 335 に参加した。 4 完だった。
感想
今回も手続き型言語 Haskell でゴリ押ししてしまった。
茶 diff の C, D が難しかった。来週は緑色コーダーに戻るかもしれない。
解法
A 問題 では
(`snoc` '4')
とか (<> "4")
が書けたら格好良かった。
B 問題 は
nubSort $ 全探索
の形で解いた。タイピングが苦手なので、空白区切りの
putStrLn
をスニペットに入れようと思った。
C 問題
ではスネークゲームを連想して混乱した。先頭の残像の位置が問われると思えば、可変配列をリングバッファとして使ったり、
cojna/iota
の Data.Buffer
に
pushBack
していけば良かった。
より上手な解答として可変配列を使わない提出が見れた。
scanl
で位置の一覧を作ってから、改めてクエリに答えていくみたい。頭を使う必要があって難度は上がると思う。
D 問題
では螺旋状に答えを作っていけば良いことが分かった。内周がこれ:
--|
|T|
|--
1 つ外側の周がこれ:
----|
| |
| T |
| |
|----
それぞれの周を描くためには、左上の頂点からスタートし、長さ \(2 i\) の辺を 4 回描いた。
accumArray
などは使わず、可変配列へ都度答えを書き込んだ。
別解としては、外周から始めて内周へと近づいていけば、壁 or 探索済みのセルにぶつかる度に 90
度回転するだけで済むため、簡単になりそう。
E 問題
は苦手なグラフ問題に見えて飛ばした。最長距離を求める不思議な問題だった。
コンテスト後に Dijkstra や 01-BFS っぽいのを投げてみたものの TLE
。もともと最短経路を求めるアルゴリズムだし、やっぱり上手く行かないみたい。同じ数が振られた隣接頂点を
1 つに潰すと DAG になり、 DP で解けるそう。後でやってみる。
F 問題
が解けなかった。右端から計算する方針は立てたものの、高速化ができなかった。
evima さんの解法
に従って \(dp[x][i \bmod x]\) を周期和とすることで upsolve できた。力こそパワー……
読書: PBT 本
実践プロパティベーステスト
を 28% まで読んだ。ジェネレータが生成したテストケースを分類し、何 %
のテストがどの分類にあたるかを確認できることを知った。
実際、ランダムなテストケースを作るだけでは、境界値を見れず素通りする確率が高い。 AtCoder
における QuickCheck
の使い方としては、実質的に総当たりをしていた。自分でループを書いても良いが、失敗したケースの表示まで
QuickCheck がやってくれる点が便利だった。
PBT 自体の良さはまだ感じ取れていない。
matklad 氏が invariant 大好きマンなので
、彼の視点を理解するためにも読み進めてみたい。