0.はじめに
土日が待ち遠しい感覚が戻ってきた今日この頃。
今回はA~Cは順調でしたが、それ以降振るわず
3完で終了。
レートは-7の777とスリーセブンを達成しました。
1. A - Decisive Battle
EとWどっちが多いかの問題。
今考えればカウンター関数で余裕な気もしますが
コンテスト時はEとWそれぞれの文字で辞書を作り
文字ごとにその字のカウントを行い
最後に多い方を出力して終了としました。
https://atcoder.jp/contests/abc464/submissions/77034598
2.B -Crop
2次元の問題。
ややこしい所もありますが、B問題らしく制約も緩いので
上下それぞれ消せる行を左右それぞれ消せる列をしらべ
その結果をもって、消したあとの表を出力してACとなりました。
https://atcoder.jp/contests/abc464/submissions/77006771
3.C - Plumage Palette
素直に日ごとの色種類数等を数えているとTLEになりそうな問題。
【考え方】
・初日に色毎の鳥数を数えて保持し合わせて種類数も保持する。
・色が変わる鳥について変わる日とその前後の色を保持する
・日ごとに鳥の色が変わったら色毎の鳥数を足し引きし、
0になった(種類減)ら種類数を減らし、1になった(種類増)ら種類数を増やす
・日ごとに種類数を出力
と、することで、TLEを回避できると考え実装しました。
【実装】
1.N、Mを読み込む
2.色毎の鳥の数を保持するリストCCをN個の項目を0で初期化
3.DC(値がリストのデフォルト辞書)を初期化(日:キー、値:日ごとの色が変わる鳥の変更前後の色をタプルのリストで保持)
4.以下N回繰り返し(A、D、B読み込み)
-1.A、D、Bを読み込みAとBから1マイナスする
-2.D=1か、A=B(初日から色が変わらない鳥)の時
-1.CC[B]に1加算
-3.D=1か、A=B(初日から色が変わらない鳥)以外の時
-1.CC[B]に1加算
-2.DC[D]に(A,B)を追加
5.ansを0で初期化
6.CCを読み込み、0以上の場合ansに1を加算(1日目の鳥の種類をカウント)
7.ansを出力(1日目の出力)
8.以下、iを2からMまで(2日目からM日目まで)繰り返し
-1.DC[i]から、tupleをaとbに一つずつ読み出す
-1.cc[a]から1減算
-2.cc[a]が0の時、ansから1減算
-3.cc[b]に1加算
-4.cc[b]が1の時、ansに1加算
-2.ansを出力(i日目の鳥の種類数)
これくらいのC問題ならスムーズに解けるようになりました。
https://atcoder.jp/contests/abc464/submissions/77014436
4.D - Celester
問題を読みbit全探索は無理があるしdpでも項目多くなりすぎるなと
諦めてEに行きました。
コンテスト後解説を見ると、dpの応用というかdpの基本というか
ある日の天気の状態毎の幸福値の最大値のみ保持する方式で
回答できることを知りました。
ABC456のD問題のように、遷移で取りうる値が少ない時(今回の場合SかR)
最終状態に至るまでの最大や最小の値(今回最大幸福度)を保持するような解法でした。
【実装】(以下Q回の処理の中身)
1.N、S、X、Yを読み込む
2.dp[0](最終日が晴れの時の最大幸福度)、dp[1](最終日が雨の時の最大幸福度)を0で定義
3.dpに1日目の状態をセットする
-1.S[0](初日の天気)がS(晴)の時、dp[1]からXを減算(晴れを雨にする)
-2.S[0](初日の天気)がR(雨)の時、dp[0]からXを減算(雨を晴れにする)
4.iを1からN-1まで繰り返し
-1.sdp(i日目が晴の時の幸福度最大値)に以下のうち大きい方をセット
・dp0
・dp[1]+Yi-1の大きい方をセット
-2.rdp(i日目が雨の時の幸福度最大値)に以下のうち大きい方をセット
・dp0
・dp1
-3.S[i]がSの時dp[1]からXを減算、S[i]がRの時dp[0]からXを減算、
-4.dp[0]にsdp、dp[1]にrdpをセット
5.dp[0]とdp[1]のうち大きい方を出力
背に先が少ない時最終値dp(と呼ぶのかは知りませんが)を使う。を肝に銘じます。
https://atcoder.jp/contests/abc464/submissions/77034128
5.E - Fill-Rect Query
Dよりは行けそうな気がして取り掛かった問題。
クエリーを逆からときつつ、イモス法を使えば何とかなるかと取り組みましたが
いい案は出てこずタイムオーバー。
コンテスト後、解説を読むと、考え方はそれほど違ってませんでしたが
一マスずつ見ていくイモス法で上書きするのはクエリーの順序(大きい方優先)とし
クエリーの順序と英大文字を連携させると言うアイデアが素晴らしいなと思いました。
【実装】
1.H、W、Qを読み込む
2.各グリッド上の文字が書かれたタイミング(クエリー順)を格納する2次元リストG(H×W)を値0で初期化する
3.リストxs(クエリー順毎の対応するアルファベット)にAをセット(クエリー実施前の値)
4.iを1からQまで以下繰り返し
-1.r、c、xを読み込む
-2.xsにを追加
-3.G[r-1][c-1]にiをセット
5.rをH-1から0まで1ずつ減算しながら繰り返し(リストの右下からチェックしていく)
-1.cをW-1から0まで1ずつ減算しながら繰り返し
-1.rが0でない時、G[r-1][c]にG[r][c]とG[r-1][c]のうち大きい方をセット
(現在見ているマスの上のマスの値が現在のマスの値より小さかったら上書き)
-2.cが0でない時、G[r][c-1]にG[r][c]とG[r][c-1]のうち大きい方をセット
(現在見ているマスの左のマスの値が現在のマスの値より小さかったら上書き)
6.Gの値をxs表に基づいてアルファベットに変換し1行ずつ出力
https://atcoder.jp/contests/abc464/submissions/77034598
以上