ganmo::cout

競技プログラミング始めました

NIKKEI Programming Contest 2019

10分で3完したあとは椅子を温めて、ぎりぎり青パフォ(1639)でした。

A - Subscribers (100点)

問題: A - Subscribers
新聞 X を購読している人が全員新聞 Y を購読している場合と、それの X と Y を逆にした場合に、両方の新聞を購読している人が最大になって、\min\{X, Y\}人。
逆に、両方の新聞を購読している人が最小の時は、なるだけ全員どちらかの新聞を購読していることにして辻褄を合わせると、\max\{0, X+Y-N\}人。
これらを出力してAC。ベン図を描くとわかりやすいと思う。

拙解 (C++):
Submission #4097313 - 全国統一プログラミング王決定戦予選/NIKKEI Programming Contest 2019

B - Touitsu (200点)

問題: B - Touitsu
i=1,2,\cdots,nについて一文字ずつ順に見ていく。\{A_i, B_i, C_i\}が相異なら、どれか二つを他一つと同じ文字に変えるのに2回操作が必要。\{A_i, B_i, C_i\}のどれか2つが同じで1つだけ違うなら1回の操作で3つ揃う。\{A_i, B_i, C_i\}がすべて同じなら何もしなくてよく、0回の操作で済む。この操作回数を足していった総和を出力すればAC。

拙解 (C++): Submission #4098593 - 全国統一プログラミング王決定戦予選/NIKKEI Programming Contest 2019

C - Different Strokes (400点)

問題: C - Different Strokes
この食事会は、高橋くんから見ると「料理iを食べると自分が幸福度A_iを得て、相手が幸福度B_iを失う」ものとなり、青木さんから見ると「料理iを食べると自分が幸福度B_iを得て、相手が幸福度A_iを失う」ものとなる。そして互いに「(自分の得る幸福度) - (相手が得る幸福度)」を最大化する。
したがって、この食事会の最適戦略はどちらから見ても「A_i+B_iが高い順に料理を食べる」となるので、最初の料理からA_i+B_iを1つ飛ばしで足していって、その総和から\{B_i\}の総和を引いた値を出力するとAC。
つまり、青木さんが全部食べると求める値が{-\sum_{i=1}^N B_i}になり、そこから高橋くんが青木さんの妨害をしてA_i+B_iを得ていく、と考えるとすんなり解ける。

拙解 (C++): Submission #4100297 - 全国統一プログラミング王決定戦予選/NIKKEI Programming Contest 2019

D - Restore the Tree(500点)

問題: D - Restore the Tree
コンテスト中にトポロジカルソートじゃないか?と思いつつ解いたが、頭の中でトポロジカルソートとヒープソートを混同しており、TLEを連発した。結局解けたのはコンテスト終了後20分ほど後になってからだった。
要するに、木の親子関係は変わらないようにDAGに冗長な辺が足されるので、これをトポロジカルソートしてノードの親子関係を求める。具体的には、この問題の制約下では根は一つしかないので、各ノードの入次数を計算してこれが0になるものを探して、これが根になる。その根を除去して、繋がっているノードのうち入次数が0になるものがもともとの木でのその根のもともとの子になる。これを頂点がなくなるまで繰り返して、制約の通りに各ノードのもともとの親を1-indexedで出力してAC。

拙解 (C++, コンテスト後解説AC): Submission #4110871 - 全国統一プログラミング王決定戦予選/NIKKEI Programming Contest 2019

まとめ

早解きばっかして序盤のいっときだけ橙パフォで100位付近とかいうふざけた立ち回りをしていました


そろそろ水色も中位にさしかかっている(レート1337)ので、ちゃんとアルゴリズムを覚えないとだめなことを今更ながら痛感しました
400点をぱぱっと解いて500点がコンスタントに解ければ青も遠くはないと信じています