AGC036

時間ギリギリで2完。Aは気づけばという感じ、Bは重かった、CとDもちょっと見たけど思いつきでどうにかなる問題には見えなかった。途中36.7、終了後36.9。立ち回りはわりとり(わりと理想的)に見えたけど、問題が難しすぎた。楽しかったかというと、やはり勝てないと総合的にマイナスの感情が支配的になる。そういうゲームをやってるということだよね(ぷよぷよとかもそう、面白いゲームはみんなそう、これからの人生ずっとそう)。

A - Triangle

10^9以下しか出力しちゃダメなのに10^18を作れってんだからきつい。図形的に少し考えていたが難しそう。開き直って外積で平行四辺形の面積を求め数式でなんとかする。10^9*10^9の正方形から削り取る感じだと難しそうだが、数式だけで見れば10^9*a-1*bみたいにできる。一つの頂点を(0, 0)に置けばこれでいい(出力の制約からはみ出ないことが確認できる)。ほんとかよって感じ。平行四辺形が10^9*10^9の正方形からはみ出てもいいことに気づいてなくて見直ししたときちょっと焦った。面積1の作り方も、「はーこれでできるんですか(わかってない)」って感じ。

B - Do Not Duplicate

ヨッシーのたまご」はやったことないです。削除された数がなかったことになり、ある数の個数の偶奇とかが保持されないのが難しいポイント。一方で、自分と同じ数をはさむことはないので、削除が起こる同じ数のペアは列挙できる(ペアの個数がO(N))。全然わからないので、とりあえずシミュレーションを書いてみる(このコードはあとで流用できる可能性が高く時間の無駄にはならない)。周期があるようだ。色々考えていたが全然わからなかった。CやDも見つつ。時間をおくと脳のステートが変わるので、解けない問題を交互にやるのはかなり効率がいいと感じる。22:30に体温を測り、その少し後に、sが定期的に空になるというアイデアへ至った。

やっと解けそうな気がしてきたが、これをどうすれば解けるのかすぐにはわからない。sの先頭にある数は次にその数が現れたときに消える、ということに気づいて、じゃあ次に自分と同じ数が現れるのがいつか前計算しておけば解けそうだとなった。n*kを超えてはいけないし、ちょうどn*k個を処理したらまさにそれが答えなので、n*kを超えたら超える直前の状態でループを抜けるようにした(慣れない処理で何回も確認した)。そして残りをシミュレーション。歩幅は最大でN+1なので不安だが、N+1個残ったら必ずもう一歩あるので半端はN個以下(0個以上)。sに入っているのは全部異なる数なので、各数についてsに入っているかの情報を保持。問題文通り削除してそこで情報を更新できる。全体でO(N)になるので大丈夫。サンプルが無限ループになるが、そういえば最初にシミュレーションをサンプルでチェックしたときもそうだった。よく見るとサンプル3のKがクソでかい。気づいてなかった。そして、Kがでかいときの処理を忘れていたことに気づいた。最初の場所へ戻ってくる確信がないので、各a[i]へ降り立ったときの位置を保持しておき、初めてループしたときにそのループをその場でしれっとn*k以下の範囲でギリギリまで回す。初めてループするまでの計算量はO(N)だし、そこからゴールまでの長さはループ1周未満なので、全体でO(N)。提出するがけっこうたくさんWA。

コードを画像として見直して、どう見ても正しいので少しコードをいじって様子見提出するが、WAの個数は同じ。地道に読んでいくと、「break。…break!?」。最初に書いたO(N^2)のシミュレーションコードの名残り。forを取り除くとbreakは自動的にさらに外のforのbreakになる。コードを流用する(そのまま使うのではなく改変する)のはあまりいいムーブではない!ちゃんと考えながら書けばそうそうミスは出ないものだ。しかし、既存のコードをいじるのは「コードを書く」思考ではない。厳密に考えることはできないのだ。

C - GP 2

碁石を使ってごにょごにょやっていたが、Nも指定されMも指定されi≠jの条件もたまにしか発動しないし考えることが多すぎて解ける気がしない。Dは読んだだけ。