AtCoder Biginner Contest 257 参加記録
コンテスト中AC:A〜D
コンテスト後にEを自力ACできたので、こちらに書いておきます。
2022/07/01 追記 Fも自力で解けたため追記
- C - Robot Takahashi
- D - Jumping Takahashi 2
- E - Addition and Multiplication 2
- F - Teleporter Setting
C - Robot Takahashi
誤った解法でかなり時間をロスしてました。
また、コンテスト後にこの記事を書いていて、嘘解法であることがわかりました。コンテスト中の嘘解法とコンテスト後の正しいと思われる解法書いておきます。
を大人と子供に分けます。
大人を
子供を
とします。
のいずれかが空の場合は、人達成可能です。以下、そうでない場合を考えます。
大人の判定が正しくなる個数を全探索します。この場合、実数の候補として、の要素のみを考えればよいです。
例えば、という位置にが居るとします。の範囲でを動かしても、子供の判定結果に影響を与えません。また、の範囲にすると、の判定を正しいものにできます。
よって、として、損をすることがないです(のケースで少し悩みましたが、これも問題ありませんでした)。
なお、やが存在しない場合でも、同様となります。
以上から、とした時に正しく判定できる人数をカウントします。の人数は明らかです。の人数は、を予めソートしておくことで、二分探索可能です。
コンテスト中の実装は以下のような感じです。
Submission #32731821 - NS Solutions Corporation Programming Contest 2022(AtCoder Beginner Contest 257)
コンテスト後に、この実装の反例が存在することがわかりました。
5
00100
10 20 30 40 50
このケースでは、実装をとして、子供の判定を全て正しくすることで、正しい判定を4人にできます。
しかし、最初の実装だと、3人になってしまいます。
なぜこのようなことになるかというと、大人の正しい判定が0人となる場合を考慮できていないためです。
これを正しく判定するためには、にを入れておけばよいです(を正しい判定となる人数に含めてはだめです)。
D - Jumping Takahashi 2
は、ある値以上ならOKで、それ未満はNGという境界があります。そこで、二分探索できないか検討します。
二分探索の判定処理にかかる見積もります。
まず、以下が言えます。
- ジャンプ力で全てのジャンプ台に到達できるかは、始点となるジャンプ台をまで全探索し、どれか1つでも達成できればよい。
次に、
- ジャンプ力、始点ですべてのジャンプ台に到達できるかは、幅優先探索によりで判定できる。
ここで、は辺数であり、今回の場合全2点間に辺がある完全グラフとみなせるため、です。よって、今回はです。
以上から、ジャンプ力で全てのジャンプ台に到達できるかという判定にかかる計算量はです。
ジャンプ力として考えられる最大をとすれば、全体の時間計算量はです。
とかでも、間に合うと想定でき、二分探索で問題ないことがわかります。
ここからが割と重要で、コンテスト中4回WAを出しました。をいい加減に大きくするとオーバーフローします。
というのも、幅優先探索で、ジャンプ台間で移動可能かの判定には問題文中の以下の式を使います。
は最大でになるため、ジャンプ力がくらいになるとがオーバーフローしてしまいます。
そこで、をしっかり目に見積もります。
と間を移動する時、
となり、右辺が最大です。また、の場合、
かどうかを判定することになるので、はを見積もれば良いことになります。実際にこれでACできました。
その他の方法としては、__builtin_smull_overflow
でオーバーフロー判定し、オーバーフローする場合は常に移動出来ることにしておいても良いかもしれません。
Submission #32746202 - NS Solutions Corporation Programming Contest 2022(AtCoder Beginner Contest 257)
E - Addition and Multiplication 2
10進数について、考えます。の上から桁目(の整数)をという様に表現します。
の時、以下が言えます。
- の桁数がの桁数より真に大きい
- との桁数が等しいとき、上から桁目までが等しいなら、 (但し、便宜上)
1番目の条件より、出来るだけの桁数を大きくすればよいです。そこで、支払う金額が最小の整数を選び、可能な限り置き換えを行います。なお、支払う金額が最小のものが複数ある場合、そのうち最大の整数を選びます。
次に2番目の条件より、の最上位桁から優先的により大きい整数に変更できないか検討します。変更後の整数についても大きい方から優先的に選びます。なお、の桁の2つ分を1つの別の整数に変更すると、桁数が減るので、変更は1対1で行います。
残金がなくなり、変更操作ができなくなった時のが答えです。
桁目についての具体的な変更方法は、残金をとすると、を払い戻したと考え、なら、桁目をとし、残金をと更新します。
Submission #32759248 - NS Solutions Corporation Programming Contest 2022(AtCoder Beginner Contest 257)
F - Teleporter Setting
町を頂点、テレポーターを辺とした無向グラフとみなします。移動時間は辺の距離とみなします。
一旦簡単のため、全て連結であるとしておきます。
に全ての未接続だった辺が繋がった場合を考えます。
最短距離は以下のパターンに限定されます。
(1) 未接続だった辺を経由しない
最短距離は、未接続だった辺を無視したの最短距離となります。
(2) 未接続だった辺を経由する
との経路に分けて考えます。最短距離は2つの最短距離の合計です。
-
から直接に行く
最短距離は未接続の辺を無視したへの最短距離となります。未接続だった辺を持つ頂点を経由してに行く
はから最も近い頂点を選びます。この時、という移動となります。最短距離は未接続だった辺を無視したへの最短距離+1です。
-
から直接に行く
最短距離は未接続だった辺を無視したへの最短距離となります。未接続だった辺を持つ頂点を経由してに行く
はから最も近い頂点を選びます。この時、という移動となります。最短距離は未接続だった辺を無視したへの最短距離+1です。
以上より、各に接続した時のからへの最短距離は、(1)又は(2)のパターンのいずれか小さい方となります。
及び未接続の辺を無視した場合の最短距離は、未接続の辺を無視したダイクストラ法を及びのそれぞれを始点として1回ずつ行えば求めることが可能です。
からに行けない時は、最短距離がになるようにすれば求めることができます。詳細は実装参照。
なお、が存在しない場合もあるので、注意が必要です(WAしました)。
Submission #32861308 - NS Solutions Corporation Programming Contest 2022(AtCoder Beginner Contest 257)