AtCoder Beginner Contest 269 参加記録
コンテストページ:
UNICORN Programming Contest 2022(AtCoder Beginner Contest 269) - AtCoder
コンテスト中AC:A〜E
Fがあと一歩だったので、書いておきます。
F - Numbered Checker
長方形領域の列は以下の2つに大別されます。 ?には整数が入ります。
0 ? 0 ? 0 ? ...
? 0 ? 0 ? 0 ...
ここから0を抜いたものを考えます。
(1) 0 ? 0 ? 0 ?...
の場合
行数を、項数を、1行目の最初の値をとすると、以下の個の数列の和を求める問題となります。
それぞれ和以下のように考えます。
というわけで、は、個含まれ、です。
これを分離すると、残りの求めるべき和は、
となるので、長方形領域の求めるべき和は、
です。
(2) ? 0 ? 0 ? 0 ...
の場合
先ほどと全く同じです。
行数を、項数を、1行目の最初の値をとすると、求めるべき和は、
となります。
以上を求めれば、当初のクエリで求めるべき答えはです。 後は、各クエリの長方形領域におけるさえ求めれば答えを得ることができます。
まず、はに依らず、以下の通り計算できます。
その他は場合分けが必要です。
(1) の場合
0 ? 0 ? 0 ? ... ? 0 ? 0 ? 0 ... ...
というケースになります。
よって、
(2) の場合
? 0 ? 0 ? 0 ... 0 ? 0 ? 0 ? ... ...
というケースになります。
よって、
以上で各クエリをで解けます。
ちなみにコンテスト中は以下のミスで解けませんでした。
- にしてしまっていた。
- を逆にしていた。
- をとり忘れた。
Submission #34954104 - UNICORN Programming Contest 2022(AtCoder Beginner Contest 269)
AtcCoder Beginner Contest 268 参加記録
コンテストページ:UNIQUE VISION Programming Contest 2022 Summer (AtCoder Beginner Contest 268) - AtCoder
コンテスト中AC:A〜D
D - Unique Username
文字列の並べ替え方が通りです。
アンダーバーの入れ方ですが、まず、アンダーバーを入れる残り個数は、文字数の合計をとすると、です。
アンダーバーの入れ方は、区別のない個のボールと区別のない個の仕切りを並べる方法の総数に一致するので、通りです。
以上から、ありうるユーザー名の個数は、通りですが、いずれか一方が大きいともう一方は小さくなるので、少なそうだと予測できます。
厳密に全て確かめたい場合は、の文字数が全て1の場合に最も個数が多くなるはずなので、まで計算してみればよいかなと思います(コンテスト中はそこまでしませんでした)。
というわけで、全探索して問題なさそうです。(書いていて気づきましたが、個数が少ないとか関係なく、鳩の巣原理からになりそうです。)
あとは、ユーザー名の生成方法です。
実装としては、順列全探索で文字列の並べ替え方を全部試し、その全てについてDFSでアンダーバーを付けていきました。詳細は実装を見てもらった方が早そうです。
Submission #34748520 - UNIQUE VISION Programming Contest 2022 Summer (AtCoder Beginner Contest 268)
AtCoder Beginner Contest 267 参加記録
コンテストページ:https://atcoder.jp/contests/abc267
コンテスト中AC: A〜D
コンテスト中にもう少しのところでACできなかったEについてコンテスト後に解けたので書きます。
E - Erasing Verticles 2
とり得る値の最小値を求める問題では、二分探索できないか疑います。今回の問題の場合、
- コストを以下にすることは可能か?
という問題を考えると、あるコスト以下は全て可能で、それより大きいコストは全て不可能という境界が存在することが言えます。
後は、コストを定めたときに、この問題について高速に判定できればよいです。
判定方法について考えます。
コスト以下の頂点があればとにかく消した方がよいです。なぜなら、そうすることでその頂点と隣接する頂点のコストを減らすことができるからです。
というわけで、以下の貪欲法が考えられます。
未削除の頂点のうち、コスト以下の頂点を1つ選び、削除する。削除した頂点と隣接する頂点のコストを減らす。これを削除可能な頂点が無くなるまで繰り返す。
この貪欲法について、例えば、削除対象を毎回全頂点から選び出しているだけでもになってしまいます。
ある頂点を削除した時、次に削除対象となる可能性があるのは、その頂点と隣接する頂点だけです。
従って、削除可能な頂点集合を管理することで、以下のように処理できます。
頂点を1つも削除していない初期状態で、削除コストが以下の頂点をに追加する。その後、が空になるまで以下を繰り返す。
から頂点を1つ選び、削除する。
削除した頂点に隣接する頂点のコストを減らし、以下ならに追加する。
が空になった時点で、全ての頂点が削除されていれば、達成可能です。そうでないなら、不可能です。
この方法は、すべての頂点の回の削除処理において、頂点を削除した時にその頂点から出る辺を1回ずつ辿るので、辺を辿るのは合計回となります。
よって、です(多分)。
これにより、高速に判定できることがわかりました。
従って、初期状態でのコストの最大値をとすれば、元の問題をで解くことができます。
コストが最大となるのは、おそらく全ての頂点にが書かれた場合の完全グラフだと思われます。
その場合でもは超えないはずなので、二分探索も十分高速です。
また、コストの下限は0になることに気をつけなければいけません(これに気づけず、コンテスト中にACできませんでした)。
Submission #34576881 - NEC Programming Contest 2022 (AtCoder Beginner Contest 267)
AtCoder Biginner Contest 266 記録
コンテストページ
AtCoder Beginner Contest 266 - AtCoder
コンテスト中AC:A,B,D
コンテスト後にC,E,Fを自力(AtCoderの解説を見ず)AC
C - Convex Quadrilateral
下のサイトに判定方法がありました。
第6回 多角形の幾何(前編) | gihyo.jp
多角形上を半時計周りに並ぶ任意の3点が与えられた時、に対してが半時計回りの位置にあればよいようです。
Submission #34484140 - AtCoder Beginner Contest 266
#E - Throwing the Die
期待値の問題が最近いくつか出題されていますが、考え方の核となる部分は同じように思います。
をターン目で得られるスコアの期待値とすると、以下のように計算できます。
ターン目は特に説明不要かと思いますので、それより前のターンについて書きます。
状態遷移を伴う期待値は、遷移先の期待値とその発生確率の積の総和をとると、遷移元の期待値を計算できます。
今回の場合、ゲーム目におけるスコアが遷移先であるターン目の期待値より高い場合に遷移しない選択をすることができます。
従って、出た目と遷移先の期待値のをとればよいです。
というわけで、の順にDPやメモ化再帰で問題を解くことができます。
Submission #34436150 - AtCoder Beginner Contest 266
F - Well-defined Path Queries on a Namori
頂点辺の単純連結グラフは木になります。そこに一辺足されると、閉路をただ1つ含むグラフになります。
閉路の異なる任意の2頂点を通るパスを考えると、閉路の進行方向によって2種類のパスが存在します。
よって、閉路に属する辺を通るようなパスは問題の条件を達成できません。
以上から、以下の解法を考えました。
1. 与えられたグラフから閉路に属する辺集合をDFSで得る
2. からに属する辺を除いたグラフを得る
3. からUnion-Findで連結成分を得る
4. 各クエリを処理する。クエリについてが、同一連結成分に属するならYes、そうでなければNoと判定する
これでACすることができました。
Submission #34413373 - AtCoder Beginner Contest 266
AtCoder Begginer Contest 265 E - Warp (兼参加記録)
コンテスト中AC:A〜D
A〜Dで特に書くことがないので、コンテスト後に解いたE問題について書いておきます(解説AC)。
問題
E - Warp
公式解説
Editorial - AtCoder Beginner Contest 265
コンテスト中に考えていた誤りの解法
コンテスト中は、全体の移動方法から、壁に経由する移動方法を引こうと思いました。
まず、全体の移動方法はです。
次に、壁を経由する移動方法を考えます。 ワープの方法を上から移動1,2,3と呼ぶことにします。
原点から移動1を回、移動2を回、移動3を回行った後に到達する座標をとすると、
という風に計算でき、一意に決定されます。
この座標が壁であるとした時に、から前述の移動回数でを通るような移動方法が何通りあるか数え上げてみます。
まず、からに移動する方法の総数ですが、それぞれ個、個、個ある3種類のボールを1列に並べる方法の総数に等しいので、
通りです。
に到着後の残りは、どのような移動方法をとってもよいので、通りです。
従って、求めたい移動方法の総数は、
です。
あとは、を全探索して、上記を計算し、全体から引いていけば良い、と思いましたが、これは
誤りです。
なぜなら、の他にも壁を通過している可能性があるため、重複して数え上げている可能性があるからです。
正しい解法
公式解説を参考に、座標ではなく各移動方法の移動回数を情報として持った、メモ化再帰で解きました。
:移動1を回、移動2を回、移動3を回行った場合の移動方法の総数
とおきます。
という式でを計算できるので、から開始してメモ化再帰することで、で全て計算できます。
となるようなを全て足せばそれが答えとなります。
操作回数が同じなら辿り着く座標が同じであることから状態がと少ないことがポイントでした。
AtCoder Biginner Contest 263 参加記録
コンテストページ:LINE Verda Programming Contest(AtCoder Beginner Contest 263) - AtCoder
コンテスト中AC: A〜E
E - Sugoroku 3
期待値DPが使えます。
サイコロを振ることを操作と呼ぶことにします。
マスからマスまでにかかる操作回数の期待値をとします。
マスからは、マスに行くことができます。
とおけば、それぞれのマスにはの確率で移動します。
また、マスに辿りつくと、マスからは(平均して)回の操作でマスに行けます。からに行くのに操作を1回行うので、マスからマスを経由してマスに辿りつくには回の操作が必要になります。
以上から、以下の式が成り立ちます。
さて、この式には右辺・左辺の両方にがあるので、左辺に移行します。
この式より、が求まっているとが求められます。
同じマスに戻るような場合、一見無限回の試行が必要なように思えますが、
このように式変形すると問題なく求められる場合があります。
次に、期待値を求めていきますが、マスの移動先が少なければメモ化再帰等で愚直に求めていくことができます。 しかし、今回は移動先が多いためとなってしまうので、もう少し工夫する必要があります。
前述の式を更に整理します。
したがって、
となります。 の部分を高速に求められればよく、連続した区間の和なのでFenwick Treeによりで求められます。
以上より、を初期値として、の順にを求めていくことで、
でこの問題を解くことができます。
(累積和を用いれば計算量が落ちるかもしれません)
Submission #33834218 - LINE Verda Programming Contest(AtCoder Beginner Contest 263)
AtCoder Biginner Contest 262 参加記録
コンテストへのリンク:■
コンテスト中AC:A〜D
D - I Hate Non-integer Number
数列の部分和に関する問題なので、部分和DPを考えます。
- 数列の項目までの部分和であって、和がとなるものの個数
今回は、何個選んだかも必要なので、情報を足します。
- 数列の項目までの部分和であって、部分和を構成する要素の数が個、その和がであるものの個数
今回、数列の要素数はと少ないですが、であり、和のとりうる範囲が非常に大きく、上記のDPは使えません。
ここで、選ぶ要素数を固定し、個とします。
個の要素からなる部分和の平均が整数となるためには、がの倍数である必要があります。すなわち、以下の条件を満たせばよいです。
つまり、部分和のだけわかれば、倍数となるかを判定できます。
そこで、以下のDPが考えられます。
- 数列の項目までの部分和であって、部分和を構成する要素の数が個であり、その和をとした時にであるものの個数
このようにすれば、のとりうる範囲もとなり、個に限定されます。
計算量は、DPテーブルを埋めるためにかかり、のそれぞれについて計算する必要があるので、だと思います。
実装はコンテスト後に見直ししたもの。
Submission #33697694 - AtCoder Beginner Contest 262