こんにちは, Shinoryoです.
今回は日鉄ソリューションズプログラミングコンテスト2023(AtCoder Beginner Contest 303)を, Pythonで解いてみた結果を書き連ねていこうと思います.
NS Solutions Corporation Programming Contest 2023(AtCoder Beginner Contest 303) - AtCoder
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
A - Similar String
文字列$S$, $T$のそれぞれ$i$文字目同士に対して, 以下のいずれかを満たすかどうかを確認すればよいです.
- $S_i$と$T_i$が同じ文字
- $S_i$と$T_i$の片方が
1
, もう片方がi
- $S_i$と$T_i$の片方が
0
, もう片方がo
例では, 引数に指定した要素がすべてTrue
と判定されるとTrue
を返すall()
を用いています. 全ての$0 \leq i < N$において, S[i] == T[i] or {S[i], T[i]} == {"1", "l"} or {S[i], T[i]} == {"0", "o"}
が成り立てばTrue
となり, Yes
を出力します.
B - Discord
ある人$i$連続して並んで撮影したことがある人の集合を$\mathrm{friend}_i$として格納します. 最終的に, ある人$i$と不仲である可能性のある人の数を調べ足し上げて, $2$で割ったものが答えになります.
単に足し上げるだけだと, 例えば人$A$と人$B$の組に関して, 人$A$目線と人$B$目線で2倍足し上げてしまうことに注意が必要です.
C - Dash
基本的には以下を繰り返せばよいです.
- $H$を$-1$させて実際に移動させる(現在座標を表す変数を更新する).
- $H < 0$の場合, 終了.
- そこにアイテムがあって$H < K$の場合, そのアイテムを消費して$H = K$とする.
アイテムは同じ場所に存在しないことを利用して, アイテムの場所を表すリストはset()
にして保存しておくと良いです. list()
で保存してしまうと, in
の計算に時間がかかってしまいTLEとなってしまいます.
なお, set()
の要素としてリストを加えることはできないため, 例では座標の数値を文字列で結合してset()
の要素に加えています.
D - Shift vs. CapsLock
動的計画法を使用します. 公式解説を引用します.
$\mathrm{dp}_{i,j}$を「$i$文字目まで入力した時点でCapsLockキーのランプが$j = 0$ならばOFF, $j = 1$ならばONである状態にするために必要な時間の最小値」として動的計画法を行います.(出典元:https://atcoder.jp/contests/abc303/editorial/6442)
(参照:2023年5月28日)
例えば, $\mathrm{dp}_{0, 0} = 0$, $\mathrm{dp}_{0, 1} = Z$となります. $\mathrm{dp}_{1, 0}$は「$1$文字目まで入力した時点でCapsLockキーのランプがOFFである状態にするために必要な時間の最小値」ですので, $1$文字目がa
だとすれば, $\mathrm{dp}_{0, 0} + X = X$または$\mathrm{dp}_{0, 1} + Y + Z = Y + 2Z$のどちらか小さい方が入ります.
このようにして, $\mathrm{dp}_{N, 0}$, $\mathrm{dp}_{N, 1}$まで計算していきます. 最終状態におけるCapsLockキーのON・OFFは問わないので, $\mathrm{dp}_{N, 0}$または$\mathrm{dp}_{N, 1}$のどちらか小さい方を出力します.
動的計画法は, 例えば再帰的な構造を持つ問題に有効です. 問題をより小さな部分問題に分割($i$文字目までの状況に分割)し, 再帰的に解を計算することで($i$文字目までの結果で$i + 1$文字目までの状況に対する解を求める), 最終的な解を得ることができるような問題です.
本ブログでも, 過去に以下のような動的計画法を用いる問題を取り扱っています.
- AtCoder Beginner Contest 189をPythonで解く:D - Logical Expression
- AtCoder Beginner Contest 210をPythonで解く:D - National Railway
- AtCoder Beginner Contest 178をPythonで解く:D - Redistribution
- AtCoder Beginner Contest 179をPythonで解く:D - Leaping Tak
- サイシードプログラミングコンテスト2021(AtCoder Beginner Contest 219)をPythonで解く:D - Strange Lunchbox
E以降
E以降は私の能力不足故に省略いたします.
参考にしたサイト等
- 「解説 - 日鉄ソリューションズプログラミングコンテスト2023(AtCoder Beginner Contest 303)」
Editorial - NS Solutions Corporation Programming Contest 2023(AtCoder Beginner Contest 303)
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
- nkmk様による「Pythonの組み込み関数all(), any()の使い方」
Pythonの組み込み関数all(), any()の使い方 | note.nkmk.me
Pythonでリストやタプルなどのイテラブルオブジェクトの要素がすべてTrue(真)か, いずれか一つでもTrueか, あるいは, すべてFalse(偽)かを判定するには組み込み関数all(), any()を使う. 組み込み関数 - all() — Python 3.11.3 ドキュメントすべての要素がTrueであればTrueを返す すべての要素がTrueであればTrueを返す...
0 件のコメント:
コメントを投稿 (Please feel free to ask me about your questions! You can use Japanese or English in the comments.)