ABC348

ABCEFの5完。

A - Penalty Kick

ちゃんと問題文読むのあきらめて、サンプルとかも見てそれっぽいのを書いて提出したなあ。

B - Farthest Point

距離の2乗は整数なのでそれで比較する。番号が小さい順にやればよい。

C - Colorful Beans

mapを使って色毎においしさの最小値を求めその最大値が答え。高速化したくなるのをぐっとこらえる。

D - Medicines on Grid

サンプル1の説明を見て、薬を使わないことも可能だと確認。スタート地点に薬がないと詰み。薬は持ち運びできない。これで問題を把握できた。実装が重くなる予感がするが、そもそも難しい。薬がある場所からBFSして、その場で薬を使ったあとに別の薬やゴールへ行けるかは判定できる。てことはO(N)頂点の有向グラフが作れて、そこでDFSしてスタートからゴールへ行けるか判定すればよさそう。たぶん解けたので、飛ばした(21:18)。

EFを通して戻ってくる。頑張って実装スピード重視で書き、15分くらいでとりあえず書き上がって提出してWA。添え字のi,jが2種類あったのと、有向辺の行き先かの判定が普通に間違ってたのと、4方向のループの添え字がhで高さのhと被ってたので、コンテスト終了後も含め3WA。

E - Minimize Sum of Distances

C_iが頂点数のようなものだとすぐ気づけてよかった。Cの合計とD(距離)の合計を管理すればよさそう。1つの辺を使うとCのぶんだけDが増える。これオーバーフローしないか?と思って計算すると、ギリギリlong longに収まる。なるほどNが微妙に小さいのはそのためか。まず、DFSして自分と自分より下のぶんを計算する。もっかいDFSして、自分より上のぶんを足す(けっこう大変)。最後に最小値を求めるところでは、初期値に頂点1の値を使う。サンプルが合わず、原因はCの合計の変数をC_iの変数に間違って書いてたことだったが、デバッグに15分くらいかかった。

(追記)全方位木DPで解き直した。確かに準備しておけばコーディング量自体はかなり少ない。

F - Oddly Similar

AtCoderで400万個の数値の入力はかなり多い。入力だけでTLEする人も出そうな。さすがに、2000*2000*999は4*10^9くらいなのでダメそう(書き方によってはいけるらしい)。2000*2000の配列を用意して、一致する個数をある程度高速に書き込めれば(あるいは書き込んだことにできれば)よさそうだが、それができるか。数列の位置毎に考えていいことに気づく。一つの位置に最大で999種類の数があり、同じ数毎にその個数の2乗の個数の場所に1を足したい。種類数が多いぶんには(計算量的に)困らなそう?問題文を読み直すと個数の偶奇だけわかればいいから足すんじゃなくてxorでいい。かなり難しそうに思ってそれでもかじりついて考えていたが、bitsetを思いついて確信はないが実装に入った。999種類の数毎にxorしたい位置を1にして、N個の数列から見て実際にxorする。一つの位置につきN^2/64程度の計算回数でそれをM回なので間に合う。実装で、数列の番号をi、数列内の位置をjとしていたので、問題文のi,jが両方数列の番号であることを忘れてNとMを間違えて最初サンプルが合わなかった。