2023年10月29日日曜日

パナソニックグループ プログラミングコンテスト2023(AtCoder Beginner Contest 326)

 Dを飛ばしてFまで五完。

コンテスト後のツイート

D - ABC Puzzle

 自力AC。

 Rの条件を満たすボードが20の五乗なので、これを全部作って調べようと思ったのだが、これだけだとTLEしてしまった。Cの一行目を満たすかどうかで枝狩りしたら通った。

 間違った方針ではないだけに、コンテスト中、時間があったとしてもこの方針に拘泥してしまった気がする。結構時間を残していないと通すのは厳しかったかも。

G - Unlock Achievement

 解説放送を見てAC。

 フロー(それも「燃やす埋める」の変形)だと分かった上でまあまあ長いこと(二時間くらい?)考えてもグラフが構築できず解説放送を見た。

 各スキルについて、「ゴール→レベル1→レベル2→……→レベル5→スタートとINFの辺を張る」、というあたりを思い付いていなかった。頂点倍加が必要? とかもっと複雑なグラフを考えてしまった。
 言われてみればなるほど、という感じではあるのだが……。

2023年10月28日土曜日

yukicoder contest 410

 Cまで三完。


No.2518 Adjacent Larger

 自力AC。全く条件が分からなかったが、ランダムテストを書いて実験して……を繰り返したらACできた。
 与えられたAに対して、1が連続する部分を圧縮したものをBとしてたとき、

・B中に2が連続するところがあったらダメ。
・B中に、[2, 1, 2]もしくは[0, 1, 1]という部分があったらダメ。

 でした。

 公式解説を読むと、なるほど確かに、という感じ。
 実際に元の数列を求めようとは考えたのだけど、2(や0)のところから考えれば良いとは思いつかなかった。

No.2519 Coins in Array

 自力AC。f(x, y)は実験して予想した。

 ただ、0になるときずっと(1, 2)をし続ければ良いというのは気付かなかった。f(奇数, 奇数)が偶数になり、f(偶数, 偶数)=0になるので、高々3ターンで0ができ、それを使って他のものを0にしていった。そのためやや面倒な実装になってしまった。

No.2520 L1 Explosion

 自力ACだけど、タグを見たし、実装問題だからね。時間をかければ解ける。

 ただ、最初座標変換せずとも解けるか(斜めにimos法をすれば)と勘違いしてしまった。(少なくとも単純な二次元の)imos法は長方形にしか使えないので、x'=x+y, y'=x-yのように座標変換しないと使えなかった。
 実装してこのことに気付いたのはちょっと間抜けだった。

No.2521 Don't be Same

 自力AC。

 頭の中で色々試したら(1, 2), (3, 4), (5, 6)のときだけ負けに思え、実装したらACできた。こういう問題は大体いつも実験しているので、実験せずに分かったのは嬉しい。

No.2522 Fall in love, Girls!

 タグは見たけど自力AC。

 bitDPというタグを見て制約をちゃんと見たら種類数が20というのがあったので、あとは実装問題でした。

 ただ、後半に

「1, 2, .... , nと番号のついたn個の玉と1, 2, ... , kと番号のついたk個の箱があります。番号順に玉を取り出し、順番に箱につめていきます。ただし、まず1の箱をつかい、次に2の箱を使い、……と、箱も番号順に使います。一個も玉の入っていない箱があっても構いません。玉の詰め方は何通りでしょう?」

 というような問題が現れ、kが小さいからDPで解いてしまった。これ、ただの二項係数ですね。気付かなかったのは恥ずかしい。

No.2523 Trick Flower

 タグを見て自力AC。

 SCCしてDPする問題。
 そこまで分かれば実装するだけかと思ったら、トポロジカルソートの順番を逆順にしてしまいWAが出て、しばらくどこが間違っているか分からず困った。
 SCCした後木DPをするのだから、SCCした後のグラフをちゃんとイメージしなくてはいけなかった。

No.2524 Stripes

 解説AC。

 二乗のDPの式を立てるのは簡単。それを形式的ベキ級数で解釈すると、分割統治してFFTを使いながら行列計算することにより高速化できる。

 行列に多項式を入れて計算すると高速化できる、というのは初めて見たと思う。それぞれの解法を知っていれば何をしているか理解するのは難しくないが、自力で解くのは結構厳しい気もする。
 

2023年10月25日水曜日

yukicoder contest 409

 Aを解いた後AHCをやろうと思っていたのに、AHCもやらずに眠ってしまった。


No.2509 Beam Shateki

 自力AC。

 x行とy列にビームを打つならば、x行目とy列目の和を前計算しておいて、その和からA[x][y]を引く。

 ……この方針で実装したが、実装量が多くなってしまった。
 今回は、ビームの位置を全探索し、毎回愚直しても間に合う。その方が実装が簡単だったか? でもあまり変わらない気もする。

No.2510 Six Cube Sum (Count)

 自力AC。

 半分全列挙は思いついたけど、メモリ制限が厳しく実装に苦労した。

No.2512 Mountain Sequences

 苦労したが自力AC。

 最大値を固定して考えると、Σ(二項係数)*(二項係数)の形になる。多分、Σの中が高速化できるんだろうな~、とWolfram alphaで実験を繰り返したら、なんとか求められる式がでてきてACできた。

 公式解説を読むと、あっさりもっと簡単な形に変形していた。とはいえ、こういうのはどうやって思いつけば良いのか。

2023年10月24日火曜日

AtCoder Heuristic Contest 025

  pretest186位→システムテスト188位。

コンテスト後のツイート

 Step3の山登り部分で、改善しているかを厳密に判定する方法があったことに気付かなかった。
 これが一番の反省点か? これを直せばかなり順位が上がるのか? と思い、ここだけ直してみたら、改善はしたものの10個くらいしか順位が上がらなかった。うーん、根本的にダメなところがあるんだなぁ。

キーエンスプログラミングコンテスト2023秋(AtCoder Beginner Contest 325)

 Fまで六完で黄色復帰。Fまでは結構速かったのに、一時間以上かけてもGが解けなかったのは反省。

コンテスト後のツイート

G - offence 

 解法ツイートなどを見てAC。

 区間DPと気付いたのは良かったのだが、

・DP[i][j]=区間[i, j)が消せるかどうか

 だと上手くいかない。
 ここで今、DP[i][j]を0/1で持っているが、もっと多くの情報を持たせれば良いのでは? と考えるべきだった。

・DP[i][j]=区間[i, j)が消せるかどうか、そして消せるならさらに何文字消せるか

 を持てば良い。そうすればDPが回る。

 自然な解法で解ける問題だった。

2023年10月15日日曜日

yukicoder contest 408

 一問も解けず。ひどい。


No.2500 Products in a Range

 解説AC。

 Aの要素を正負で分け、正と負でそれぞれ連続区間を取るのでは……などと考えていた。だが、色々な場合を考え損ねて迷走。
 特に、lとrを正負で分ける方針は思いついたのになぜか必要がないと結論してしまった。

 落ち着いて場合分けすれば解ける問題くらいはちゃんとやらないと。

No.2501 Maximum Inversion Number

 問題のタグだけ見てAC。

 全部の要素を同じくらいの個数にすると転倒数が大きくなりそう、と考えたら思いつけた。

2023年10月14日土曜日

Codeforces Round 903 (Div. 3)

 Eまで五完。Fが解けなかったのはまずい。


F. Minimum Maximum Distance

 解説ツイートなどを見てAC。

 コンテスト中は、「木ではなく一直線の場合は三分探索で良さそう。三分探索を木上に拡張できる方法はないか?」と考えて困っていた。
 そのせいで問題への考察を怠っていた気がする。

 今回は、印がついている頂点のうち考えるべきものが絞れることに気付かなくてはいけなかった。端の頂点しか考えなくて良い。
 「端」というのが何かというと、印がついている頂点たち(とその間の頂点)を結ぶ木を作ったとき、その直径になっている頂点だけ調べれば良いということ(というか、直径/2の切り上げが答えである)。
 言われてみれば当然に思えるのに、結構時間をかけても気付けなかった。



2023年10月9日月曜日

AtCoder Regular Contest 166

 Cまで三完。

コンテスト後のツイート

D - Interval Counts

 解説AC。

 コンテスト中は、最小値を取りたいということから、(-∞, ?]や[?, ∞)という区間をいっぱい作りたい……というところから考えてしまったが、この方針はあまり良くない。

 もっと根本的に、[L, R]という区間をいくつか張る問題だということを意識するべきだった。
 そうすると、Yの隣接差分を見ることで、区間が何個始まるか、何個終わるか、の差分が分かる。しかし、ある場所で区間が終わり、同時に始まったとすると、その二つはくっつけた方がいいのは当たり前。
 ということは、Yの隣接差分は、「各場所について区間が何個始まるか、もしくは何個終わるか」を表していることになる。そうすると、貪欲に(できるだけ昔始まった区間から)消費していった方が良いというのは自然。

2023年10月8日日曜日

Educational Codeforces Round 151 (Rated for Div. 2)

 Dまで四完。

コンテスト後のツイート

E. Boxes and Balls

 こたつがめさんの実況放送の振り返りを見てAC。

 コンテスト中、左端の1はどこからどこまで詰められるのだろう? などと考えていた。大まかな方針はそれで良いのだが、「どこからどこまで」ではなく、全てのnについて試さなくてはいけなかった。

 各i in [0, n)について、何番目のボールをそこに置くか? そうした場合の移動距離はいくつか? というDPを考えると三乗のDPになり、それを枝狩りすると通る。

 三乗DP自体は自然なものなので、それは思いつかなくてはいけなかった。

yukicoder contest 340

 A一完で終了。


No.1909 Detect from Substrings

 解説AC。

 最初の二つの文字列から答えを絞るのがポイントだが、そのためには、「答えが少なそう」と気付かなくてはいけない。
 絞れると分かった後の考察も結構難しいが、「異なる最初の文字」に注目して考えれば良い。

 分かってしまえば難問という程ではないのだが、問題の見た目がシンプルなのに、腰を落として考える必要があるのが難しい。

No.1910 High Element on Grid

 $R_i$、$C_i$が、「A[j]がA[:j+1]の最大値になっているようなjの個数」を表していることは分かったが、その構築をどうやるか?

 ……結構考えても分からず解説を見たが、あまりにも単純でびっくり。一行目一列目が特別だと気付いていなかった。

2023年10月7日土曜日

Pinely Round 2 (Div. 1 + Div. 2)

 pretestはEまで。

コンテスト後のツイート

F. Divide, XOR, and Conquer

 こたつがめさんの放送の振り返りを見てAC。
 いや以前に、この放送や公式解説を見たときは分からなくてしばらく放置していたのだけど、今もう一回きちんと見たら理解できた。

 区間DPでいけそう、と言われればそういう気はしてくる。(n=10000でも想定計算量が二乗の可能性があることに注意しよう)
 ただ、区間DPが二乗で済むと思いにくいし、また、空間計算量が線形で済むと気付きにくい。

 区間DPでいけると言われれば自然な解法に思えるが、それでいけるとは思いにくい問題な気がする。

・Sを累積xorとする。
・最上位bitに注目するのは自然。
・長さが長い区間から区間DPしていく。

・[l, r]でS[l]とS[r]の最上位bitが同じなら、[l, n], [n, r] for any n(ただし、それぞれの区間は元のものより短い)に遷移できる。

・[l, r]でS[l]とS[r]の最上位bitが異なるなら、そのbitをxとすると、[l, n]に遷移できるのは、S[l]^S[n]のx bit目が異なるとき([n, r]も同様)。これを覚えておきたいが、そのとき、「S[l]が左端になるときは、右端とx bit目が異なれば良い」とさえ覚えておけば良い。

・この後、xと異なるyについて、「S[l]が左端になるときは、右端とy bit目が異なれば良い」を覚えておきたい状況が存在するかもしれない。そのため、(1<<x)|(1<<y)と記録しておけばOK。



yukicoder contest 407

 Cまで三完。


No.2495 Three Sets

 コンテスト後自力AC。

 A, B, Cを大きい順にソートしておき、それぞれ何個取るべきかを三分探索で求めたらACできた。
 コンテスト中にこの方針は思いついたもののあまり自信がなくて実装せず、コンテスト後に実装したらAC。

No.2496 LCM between Permutations

 WAが出て、WAが出たtestcaseを見てデバッグしてAC。

 (1, i)を全て聞いてみる。
 それで、Bの中に1があるところを特定できれば簡単。そうでなければ特定できたもののうち最も大きい素数を考え、そのindex indを使って(i, ind)を聞く。

 そういう感じで、AかBかで特定されていない場所が二個以下になるまで聞く。
 そうしたら、片方が1と分かるので、それを利用する。

 ……みたいにしてACできたが、多分、Hackできますね。(多分できなそう。追記しました)

 解説を読むと、N/2より大きい素数の位置がN+1回あれば見つけられることを利用していた。そういう素数の位置が分かると良いことには気付いていたが、N回で見つけられなかったとき、もう一回で見つけられるとは気付いていなかった。なるほどです。

 (追記)
 自分の解法は正当な気がしてきた。N/2より大きい素数をpとして、(1, i)を全部聞いたとき、A[i]=pならばBは二要素以外全て明らかになる。それ以外だったら、Bの中のpが最大の素数になる。
 だから、正しそう。

No.2497 GCD of LCMs

 解説AC。

 一般グラフの単純パスたちの持つ性質を考えるという問題が、ダイクストラで解けるとは考えもつかず、結構びっくりした。

 とはいえ冷静に考え直すと、一般グラフのサイクルとかを扱うのは難しい(サイクル基底を使う、とかはあるけれどそういう問題ではなさそう)し、何か上手いことをして最短距離問題に持ち込むくらいしかないのかもしれない。

2023年10月5日木曜日

yukicoder contest 390

 Eまで。

コンテスト後のツイート

No.2319 Friends+

 解説AC。

 解説で、bitsetで解けると書いてあったので、その方法でAC。
 平方分割を使うのだろうと考えていて、実際それでも解けるのだが、bitsetを使えることも思いつけなくてはいけませんね。
 ただ、高速な言語ではbitsetで通せても、PyPyなら平方分割するしかない、という場面もあるのだから、平方分割でもちゃんと解けなくてはいけなかった。

 友人が多いか少ないかで場合分けするとは思ったけれど、その生かし方が分からなかった。そこは冷静に考えるしかないのだが。

2023年10月3日火曜日

yukicoder contest 391

 ABの二完。


No.2336 Do you like typical problems?

 自力ACしたが、非常に時間がかかってしまった。難しい問題ではないと思うが、大まかな方針が立った後、立式しても自分が何を求めているか分からなくなってしまう……。

 想定解とほぼ同じ方法だが、想定解でいもす法を使っている部分で、平面走査を使っている。
 TLEできつくなってしまったのはそのせいなのだろうか? 定数倍高速化を頑張ったらACできた。

No.2337 Equidistant

 解説AC。
 大体の方針は分かったが、LCAがちょうど間にあるケースを考え損ねていた。典型だけど、そのケースを見逃しやすい。

 ダブリングによるLCAを久しぶりに実装した。ライブラリに入れておこう。