ABC264参加記

速解きをしただけの人、Ex詰めるべきだった

42:13 + 1ペナ 6完 162位

A "atcoder".substr()

言われてみるとタイトルに答えが書いてある

意識してなかったですが、substr()を使って書きました

(AC 1:08)

 

B Nice Grid

端からの最短距離で色が決まっていることが分かります

一瞬多点BFSしようかと思ったけど、冷静になると端からの距離を計算してそのminをとればよいことに気づきます

あとは偶奇を求めるだけ

(AC 5:45)

 

C Matrix Reducing

ひさしぶりにbit全探索きましたね

Cに出るけどdiffが高くなると評判のやつです

制約が小さいので、とりのぞくところを決め打って一致するか見ればよいです

ざっくりみて2^10 x 2^10ですが、h2,w2と一致しない時は無視できるのでかなり高速に動きます

(AC 12:58)

 

D "redocta".swap(i,i+1)

これも非常に典型的な転倒数を求める問題です(ソート回数=転倒数)

もう少し列が長いとBITなどを用いたO(NlogN)の解法が必要になりますが、今回は愚直にチェックしてあげればよいです

具体的には与えられた文字列に対する位置を2つ決めて、その位置がもとの"atcoder"で逆転していないか確かめればよいです

(AC 15:40)

 

E Blackout 2

このあたりからちょっと難しめになってきます

まず、こういう「辺を切る」操作はかなり扱いづらいので、「逆からみる」とうまくいくことが多いです

この典型はABCに限っても何回も出ています

 

出題例:

ABC229-E Graph Destruction 

E - Graph Destruction

ABC120-E Decayed Bridges

D - Decayed Bridges

 

とりあえず逆からみることにして、「今発電所とつながっている都市の数」をどうカウントするか考えます

解説のように超頂点をつくるときれいに書けますが、そこまで考えられなくても頑張ると解けます

計算するのに必要なものは

「そのグループは発電所とつながっているか?」

「そのグループには何個都市があるか?」

の2つです

これがわかれば、新しく発電所を含むグループとつなげるときに、都市の個数を加えてあげればいいことになります

 

これを配列などで管理してみましょう

どっちでもやることは同じなので、「そのグループには何個都市があるか?」について考えてみます

もし、そもそも同じグループにいるなら新たに考える必要はありません

2点u,vが違うグループにいるなら、新しくできるグループの個数は

(uを含むグループの都市の数) + (vを含むグループの都市の数)

になります

 

では、(uを含むグループの都市の数) をどう計算すればよいでしょうか?

グループをくっつけたときに、そのグループに含まれる都市すべての値を更新することでも計算できますが、最悪の場合O(N^2)の計算量になります

そこで、UnionFindにあるleaderなど、グループを代表する頂点だけ更新するようにします

そうすると1回の更新で1つの値しか変化しないので十分高速になります

発電所があるか否か?も同様に管理すればよいです

(AC 31:48)

 

F Monochromatic Path

制約を読むとかなり大きいので、できることが限られてきます

今回「右か下にしか動けない」という条件があるので、1度通り過ぎた行や列に戻ってくることはありません(ので、その場所以前の情報を考慮する必要はありません)

また、今いる位置が0なのか1なのか?は「その行の反転回数 + その列の反転回数」にのみ依存します

よって、必要な情報は[今のマス目はどこか][その行は反転したか][その列は反転したか]の3つになります

 

ということでこれらを素直にDPに落とし込んでいきます

dp[i][j][k][l] = マス(i,j)にいて、行が反転(k=0,1)、列が反転(l=0,1)しているときの最小費用

とDPを定義すると、

新しく移動するときに色が異なるかどうかを確認して、違うなら進む先の行or列の色を反転させる必要があるので、そのぶんのコストを加えるとすることで遷移できます

(AC 42:13)

 

G String Fair

大胆予想!!最適な文字列は3文字以下かINFとしたら嘘でした

最短経路、文字列だとよくあるパターンなのに出てこなかったの反省

 

総括

いいところF