ARC140

3ペナ3完。BCの実装とデバッグつまんなかったな~、ひょっとしてARC中の時間の価値ってそんなに高くないですか?

得るもの(楽しかったとか勉強になったとか)がないのでブログを書くのにも普段感じないしんどさがある。

A - Right String

Tは長さf(T)の文字列をlen(T)/f(T)回繰り返したものでありそう。こういうの証明難しいんだよな。そのくせ大抵正しいから時間をかけすぎるわけにもいかない。何考えたか忘れたな。ああ、3回rotateして一致するなら3文字ずつ区切って全部同じ文字列になることを確認したんだ。これも状況証拠でしかないが、約数にしかならなそうなので小さい順に試す。その場合の最低限必要な変更回数は、区切った文字列の各位置について必要な変更回数がわかりそれでその周期にできるのでそれでOK。位置毎に文字数を数えて一番大きいのに合わせる。計算量はO(N^2)には収まるのでOK。

B - Shorten ARC

どちらでも好きな操作ができると誤読していた。その場合、ARCをACに変換するとそのACの2文字はもう使われることがなさそう(どっちも相手が消えない限り使えない(どちらの操作も文字をいくつか消す操作))なので、Rに変換する操作だけをすることになる。R視点で考えて、隣接するAとCを使っていくしかない(Rは消えないのでRで区切られた区間の文字たちしか使えない)。つまり、Rから左に連続するAと右に連続するCを数えて小さいほう回だけ操作できる。提出してWAが5個。

しばらくして誤読に気づく。2回セットで考えると、その2回で必ず一つのRが使えなくなる(消える)。残り1回のやつを消すのは最適そうだけど、他を多い順にやるか少ない順にやるかけっこう難しい。1とそれ以外で分けて、priority_queueに1より多いのを入れて1の個数も管理する。多い順に使い、消すのは1を優先する。どちらかが0個になったら、1しかなかったら操作回数が1の個数と同じなのは明らか。そうでないとき、1減らして消す(計2回)という操作が残ったRの個数だけできる。提出して今度は13個WA。0をはじいてなかった。

C - ABS Permutation (LIS ver.)

てきとうにスコアが高そうな順列を作ってみる。3 2 4 1 5みたいの。これが自明に実現できるケースはそれでいい。そうでないとき、逆から考えると差が1からN-1まで現れる順列はさっきのやつしかないとわかる。スコアはN-2以下になるが、Xが半端な数だったときに構成できるかというのが問題。これは、1 2 3 4 5のように並べたものから順に数を拾って順列を作ることを考えて、X=2なら1 _ 3 4 5から3 4 1 5と拾っていけば距離が狭義単調増加にちゃんとなっている(毎回、前回の経路を含んでいる)。これで解けたが、実装があまりにも大変。

0-indexedで考える。基本、N/2(切り捨て)の位置から左右左右と取っていくが、Nが偶数でX=N/2-1のときは右左右左とする必要がある。Xを使わないときはXを除いた数列を作り同じような処理をする。それだけだけど、実装はけっこう考えることがある。言葉にするのが面倒だから、実装はこんな感じ。開始位置を、右左右左のときにずらしてなくてWA。まあこの実装になるまでかなり試行錯誤してるので、力不足でしかない。

D - One to One

まず、全部-1のときを考える。これ置換でもないんだよな。連結成分の大きさの期待値とかそういうので色々な方面から攻めてみたがダメ。最初から各連結成分のサイズを決め打つとか。これも同じ個数のどうやって区別するん。それに、何か考えても最初から辺がいくつかあるというので完全に不可能になる。