ABC198

WA投げ大会。5完。ぷよぷよ最強リーグを見ていて、すごい試合を見ているという実感があり、視聴を途中でやめてまでしてABCに出る価値はあるのだろうかとわりと本気で考えていた。でもまあやっぱりリアルタイム参加する価値が高いねこのABC。わりとスピード重視でやっていた面はあるが、さすがにわからされた。今日は順位表を見ずにやっていた。

A - Div

15個のお菓子があるとしてA君は1個から15個まで取れるなと考えて「ん?」となる。相手にも1個以上ないといけないから14個までだ。1を引く。お菓子が1個のときは0通りで他にコーナーはなさそうなので提出。

B - Palindrome with leading zeros

文字列として受け取るのはそう。さすがに全探索した。0を0個から9個まで付けるのを試す。

C - Compass Walking

適当に曲がればぴったりにできるので、割って切り上げ。誤差が心配なのでepsを、引く(最初間違えて切り捨てにしたし足すのか引くのか混乱する)。誤差見積もりできてないけどこんなもんでしょで提出してWA。最初にちょっと考えてできなかったので捨てた整数でやる方法を考え直す。答えは明らかに10^6より小さいので、その回数で行けるか小さい順に全部試す。小さい順ならオーバーフローもしない。またWAでびっくり。ああ、1歩より近い場所かあ。

普段のABCで誤差に目を向けさせておいてこれはいい目くらまし。この揺さぶり方!これunratedだから楽しめてるけどratedだったらどう感じたんだろうね。

D - Send More Money

覆面算。これは子供のころからニコリに触れていたので経験がある処理。覆面算なら当たり前だが、違う文字は違う数である必要がある。まず、文字を0から9の10種類の数に変換する。これは見つけた順に番号を振っていく(文字を番号に変換するテーブルを作りながらという感じで)。10種類を超えたらUNSOLVABLE。10の階乗は、ググって300万くらいなので、全探索できる。頭に0がないことをチェックする。これもWAで原因がわからなかったが、10文字は9*10^9とかでintじゃオーバーフローする。

E - Unique Color

簡単そう。「頂点 x 以外に存在しない」がかなり読みづらく、その負荷もあって誤読しサンプルの説明が違うように見えてClarを送ることすら考える。なんか頂点1の色が関係あるように勘違いしてた。末端がパスの中でその色である唯一の頂点ならいいということか。DFS。これ、色を表す数がN以下だと実装しやすいんだがな。色が存在するかの長さ10^5の配列を更新しながらDFSして「よい頂点」をvectorに入れていく。これもWA。各色の存在で01を持っても更新できないじゃん。各色の個数を持てば更新できるし存在してるかもわかる。

F - Cube

いくらWAを出そうが全完すればいいんだと言いつつ、全然解けない。思いつくあらゆる方針が解かれることを拒んでいる。まず6個に分けるだけなら簡単で、正の数だからSから6を引いておいて5個の仕切りを入れる。回転して同じになるかの判定は、上にする面を6通りと回転4通りで24通り試せばよさそう。「3個が同じ数で残りは全部違う数」みたいなタイプがいくつあるかDFSを書いて調べると11通りしかない。全部出力させる。各タイプが何通りあるかわかればいいが、どうにも無理そう。答えが24倍になるような問題は何かとか6の階乗倍だったらどうかとか考えるがわからない。難しそうなところを突っ込んで考えたり、いやそんな難しいはずはないと引いて楽に考えてみたりの繰り返し。

いつも「なんで自分がこんなセットでratedなんだ」と思っていたが、いざ黄色になってみると「ABCボロボロなのにunratedでごめんなさい」だ。

(追記)ACとった。解説の「解法2 場合分け」が自分の考えていたことに近かったのでそれで。書き込む数を座圧したときのパターン2^5通りで場合分け。例えば大きい2つが同じ数で残りの4つも同じという場合、(予めSから6を引いておいたとして)x*2+y*6=S-2 を満たす非負整数x,yが何通りかという問題になる。包除原理を使い、xが正の通り数とyが正の通り数を足してxもyも正の通り数を引けばよい(ここができるものだとコンテスト中は思わなかったし、解説を見ても今日(木曜日)までわからなかった)。これで漸化式が立ち行列累乗で計算できる(行列は最大で21*21になるが、行列累乗を32回やるだけなのでまあ問題ない)。それぞれの書き込み方が何通りあるかは、24通りの置換を全部試し6進法の数とみなして一番小さいものをunordered_set(定数倍重いけど32回*6要素のnext_permutationなので)でカウントする。2方向の回転を実装すれば列挙できて、上を0下を5真ん中をぐるりと1234にしておけばそのうちの片方は楽。6個の各面を上に持ってきて回転で4通りずつ。いやあ長かった。