/ 最近 .rdf 追記 設定 本棚

脳log[2021-03]



2021年03月10日 (水) [AtCoder] 自分はぼんくらなので最近まで気がつかなかったんだけど、(AtCoder Problems で確認できる) AC 数って2通りの意味があるんね。そしてランキングに名前が出るような人にとってはほぼ例外なく2番目の意味(……でもないか。1000 超えてても埋まってなかったりする)。解いた問題の数、ではない。解ける問題の数、である。どれだけ多くどれだけ難しい問題を解く能力を持ち、実際に解いたか、を表す数なのである。■数えてみたら自分の AC 数は 1000 を超えたところで頭打ちになる。そこが第2のスタート地点と言えるだろう。解ける問題を増やしていくつらい道のりの。


2021年03月13日 (土)

最終更新: 2021-03-15T22:56+0900

[AtCoder] パナソニックプログラミングコンテスト(AtCoder Beginner Contest 195)F 問題 Coprime Present

本日の ABC。1時間かけて ABCD の4完で、残り40分考えて E 問題が解けずに終わった。ゲーム問題苦手。勝ち筋とか必勝法とか、さっぱり見えない。「自分はこの、先攻後攻が決まった瞬間に勝ち負けが見えるゲームを、きっと楽しくプレイできるんだろうなあ。

本番中に E 問題が行き詰まっている最中に F 問題をタイトルだけチラ見していた。Coprime の単語が見えた瞬間にあきらめた。別の問題だけど先々月に「Coprime はまた解けなかった。」 完全に苦手意識を持っている。素数とか見たくない。

 提出 #20911347 (TLE×19 / AC ×17)

割と大きめのサンプル3が通ったのでいけると思ったが TLE だった。

考えたことを順番に。

  1. 制約「B−A≤72」があからさまな弱点。
  2. A と B 自体は 10^{18} になりうる大きな数なので、互いに素をどのように確かめるか。
  3. 72 以下の素数で割ってみればいい。
  4. [A,B] の区間から作ってはいけないペアが列挙できたが、これを 2^{B-A+1} 通りの組み合わせからどう除外するか。
  5. (迷走) ペアの左側をマージしたビット列とペアの右側をマージしたビット列を用意して、全 2^{B-A+1} 通りを振り分けよう……実行が終わらない。
  6. (迷走) ペアを併合したグループを使って解けないか……解けない。
  7. 愚直にカードを1枚ずつ引いて、使う場合と使わない場合で深さ優先探索を……これがさっきの TLE 提出。

 提出 #20911691 (AC / 357 Byte / 221 ms / 14628 KB)

このとき(緑diff精進3問)解いた問題の1つが「ABC 115 D - Christmas」なんだけど、素直に問題の通りに書いた最初の版が明らかに TLE を免れなくて、ださいけど if を使って2回の再帰呼び出しを1回に節約するパスを追加することで AC になっていた。

倍倍ゲームになりうる再帰構造には特別な警戒が必要だということと、それが反転したときに改善効果が劇的だということを学んでいた。今回も最後の lambda F に2行追加して AC。

 「(迷走) ペアを併合したグループを使って解けないか……解けない。」

たぶんグループの作り方が間違っていた。二次ペア三次ペアと芋づる式に相互グループを作るのでなく、それぞれの数ごとに一次ペアのグループを作って、そのサイズでクラス分けをすれば、計算で答えが求まったのではないか。計算の材料にする数字が誤っていたから求まらなかったのではないか。いやでもそのクラスには公倍数の情報が抜けてるのか……。

 「72 以下の素数で割ってみればいい。」

組み合わせた結果をフィルタリングするよりも、フィルタリングした結果を組み合わせるべきだったのではないか。SQL がそうでしょう? JOIN する前に WHERE で絞るべきなんだ。WHERE に似ていても HAVING では遅いんだ。

全探索がダメでもある種の探索が許されていたあたり、今日の制約には優しさが感じられるなあ。


これに関連した @kyopro_friends さんのツイートを考えていた。

競技プログラミングをするフレンズ @kyopro_friends

アライグマ「F問題は、COLOCON2018C『すぬけそだて――ごはん――』の難しい版なのだ! gcd(x,y)=gcd(x-y,y)≦|x-y|だから、72以下の素数の倍数が重複しないようにすればよくて、どの素数の倍数をもう使ったかでbitDPすればいいのだ!」

gcd(x,y)=gcd(x-y,y)≦|x-y|」ってつまり……

  • 10000 と 10010 のように近接した2数があるとき、その公約数が 10000 近辺にあることはないのだなあ。
  • 大小2つの数とその差(正の方)という3つの数があるとき、これらは GCD を共有しているのだなあ。
  • x-y を繰り返して行き着く先は x%y だけど、なんだかこれってユークリッドの互除法……

というような発見があった。ものがよく見えていないと「新発見」が多い。ユークリッドの互除法まで見つけてしまった。開拓者か研究者に向いているのではないか。


2021年03月16日 (火) [AtCoder] 昨日から AtCoder Problems が真っ白で困っていた。Array.prototype.flatMap を補ってとりあえず大丈夫。どのブラウザも OS を選り好みするせいで代替になり得ない。■なんかそうしたら以前から真っ白だった AtCoder Pie Charts タブまで正常に表示されるようになった。棚ぼた。 ABC や ARC の問題一覧が見られる Table ページで自分の状態(AC/NotAC/NoSub)も見られるようになっている。あれってユーザースクリプトじゃなかったんか……。


2021年03月17日 (水)

最終更新: 2021-03-24T16:47+0900

[AtCoder] AtCoder Beginner Contest 067D 問題 Fennec VS. Snuke

解いたあとで他の人の Ruby での解答を見たらバリエーションがいくつか見られた。

 解法1:キューを2本用意してフェネック、すぬけくん双方のスタート地点から各ノードまでの距離を幅優先探索などで確定し、それからノードの塗り分けをする。

これが一番多かったと思う。公式解説に書かれている通りの手順。

 解法2:1本のキューでフェネック、すぬけくんが交互に陣取りをしていく。

これは Ruby で最速の qib さんの提出 #20369253 (191 ms) の解法。

公式解説にはこう書かれている。

マス i と j の距離を d(i,j) として,マス i の色は d(1,i) ≦ d(N,i) ならば黒,そうでなければ白となる.結論としてマス 1 とマス N の 2 点から幅優先探索や深さ優先探索などを行うことで O(N) でこの問題を解くことが可能である.

解法1はたしかに解説通りの手順ではあるが、解答にあたり具体的な距離まで知りたいわけではなく、距離の大小関係だけ知れれば十分なのだ。

解法2の手順は(スタート地点からの距離を測定する)幅優先探索に則っているのだが、一見すると1手につき1マスしか塗れないゲームのルールに反しているように見えるのが難しい。同じことは解法1にも言えて、「マス i の色は d(1,i) ≦ d(N,i) ならば黒,そうでなければ白となる」が納得できるかどうかに尽きるのだけど、解法2の手順がなまじゲームに似ているせいで考えてしまう。

 解法3:自分の>提出 #20999230 (208 ms) やや遅く、メモリ消費も多い。

フェネックとすぬけくんの行動原理として想定したのは公式解説のものと同じ。見立てだけが異なる。どういう見立てだったか。

フェネック(すぬけくんでもいいが便宜上フェネックを選ぶ)のスタート地点を木の根と定めて、すぬけくんのスタート地点の深さを知る。すぬけくんは移動可能範囲を広げるために根に向かって移動する。フェネックはすぬけくんの移動可能範囲を狭めるためにすぬけくんに向かって移動する。出会うのは中間の深さ。すぬけくんは根に向かって移動できなくなった地点を根としてその子孫ノードだけを塗ることができる(だから一直線に根(フェネックのスタート地点)を目指していた)。

結局のところこの問題は一本の辺を見つけ出す問題だった。頂点集合をフェネック側、すぬけくん側に分ける辺がどれかを見つける問題だった。

その手順として幅優先探索(解法1)とその応用(解法2)と深さ優先探索(解法3)とダイクストラ法(未紹介)と、いろいろな方法があって、実行速度の差があった。同じ線形時間でも1回なめるだけで済ませられるのか、2回か、3回か。

 AtCoder Beginner Contest 148F 問題 Playing Tag on Tree

今日@2021-03-23 たまたま取り組んだこの問題が同じ方針で解けそうだった。

2地点から深さ優先探索で陣取りをしていって、中央付近でにらみ合って、それからどれだけ相手陣へ侵攻(自陣へ後退)できるかを数えれば答えになりそうだった。

 提出 #21207034 (WA×1 after_contest_01)

きっちりと隙を見せない after_contest に撃ち落とされましたとさ。

競技プログラミングをするフレンズ @kyopro_friends

サーバル「ABC148F『Playing tag on tree』にafter_contestを追加したよ! 不等式に等号を入れるか入れないかを間違ってるコードが落ちるようになったはずだから確認してみてね」https://t.co/jcHP4lHFhg

 提出 #21208328 (AC)

不等号などなかった。先攻後攻を入れ替えたのと、自陣へ逃げ込もうとしてうっかり中立地帯へ迷い込まないように道を塞いだ。

当初方針のまま after_contest に対応したが、どうにも不自然に頑張ったようなコードになってしまった。この問題に関しては、想定解法通りに2通りの距離表を見比べて答えを選び出すのが良かっただろう。

ところで ABC148 はオンタイムで参加していた。A-D まで灰 diff で、E 問題に至ってもギリギリ緑という低難度回。F 問題でやっと水 diff 中位だったらしい。当時1時間を残していながら解けなかったのがこの F 問題。何を考えて解けなかったか。

木の上で追いかけっこをする2人がすれ違うことができない、ということが認識できていなかった。だから偶奇が適切な部分木を選んで逃げ込むことで追跡が躱せるような気がしていた。それじゃあこの但し書きが嘘になるのにね。「なお、ゲームは必ず終了することが証明できます。」 そんなん考えたら青 diff 上位の「DFS Game」より難しくなるってのにね。


2021年03月20日 (土) [AtCoder] 今日の ABC196D 問題 Hanjo。Ruby でも(ほぼ)全探索を許してくれる慈悲深い制約に助けられた。終了1分前に ACE 問題 Filters。考え方は合っていたけど詰めが甘かった(RE, WA)。愚直解法とランダム入力で答えを突き合わせてデバッグをした(AC)。コンテスト中にこれをする余裕はない。


2021年03月21日 (日) [AtCoder] 今日の ARC115。いつものように 20 時までにお風呂に入って 21 時前にあがって PC 前でスタンバイしていたら、気付いたときにはもう残り時間が半分を切っていた。まあ、そういうこともある。帰宅が19時過ぎなのでもとから20時スタートは厳しい。時間が合わなくて1時間遅れで参加した ABC も過去にはあった>ds14050@ABC156。そのときのパフォはABC3完で177。プラス1時間で D 問題まで解けていたのがくやしいところ。ARC の A 問題1完最遅レベルのパフォは……知りたくない。■今日のパフォーマンスをどのように受け止めるか。ありうる理想世界の自分は ARC の A,B,C 問題くらいは1時間でささっと解けているはずなので、1時間で3問解いたパフォーマンスが2時間で3問解いたかのように評価されるのは不本意であるが、1時間で1問しか解けなかった、途中で0完も覚悟した、低パフォーマンスの第一の原因は自分の残念なおつむにある。残念なことであるなあ。


2021年03月22日 (月) 「進入不可」と「進入禁止」はどちらが強い抑止効果を持つだろうか。人によるだろうか。■進入不可……本当に入れないかどうかは確かめてみなければわからないな!■進入禁止……なんで禁止されてるんだろう。誰が禁止してるんだろう。まあ、入って入れんこともなさそうだし、いっか。■だいたいこんな感じ。ありとあらゆる落とし穴に一度以上はまることを自認している。一度目は(なぜか人が避けて通る)ショートカットの疎通を確かめるために(穴に落ちるまで穴があるかどうかは不確かだ)。二度目以降は迂闊さのために。■再掲「シマノのハブの説明書にクイックリリースのハンドルの向きを規定する記述があって、それに続けて、茂みに突っ込んだりしたときに強制的に開放されないためだとかなんだとか、そうする理由が一緒に書かれていた。とてもとても素晴らしいと思います。納得できる理由がなければ動けない人間なので!」 禁止するにも作法があるのではないか。そこまでする義理はないって? いかにも。しかし実効性を求めるときには考えてもいい。