2024-11-18
Codeforces Round 988 (Div. 3)に参加した
Codeforces Div. 3の参加記.
11月17日に開催されたCodeforces Round 988 (Div. 3)に参加し,ABCDの4完で2304位だった.
久しぶりに出たら大失敗回になってしまって悲しい.Eを飛ばしてFに行ったら変な沼にはまった.
A - Twice
問題概要
長さの数列が与えられる.この数列に対し,であるような異なる要素を選んで削除するという操作は最大で何回行うことができるか?
制約
考えたこと
数列の中にであるような要素がちょうど個あったとすると,その要素からは回の操作をすることができ,それ以上の回数の操作はできない.よって答えは
である.
提出:https://codeforces.com/contest/2037/submission/291949756
B - Intercepted Inputs
問題概要
長さの数列が与えられる.正の整数であって以下の条件を満たすものをひとつ出力せよ.
- ある個の整数とをある順に並べた数列がに一致する.
制約
- となるが存在する
- 条件を満たすが存在する
考えたこと
要素数の関係から,との間にはという等式が成り立つ.
の候補を全探索する.であると仮定すると,がの倍数ならばと決まる.よってあとは数列(からを除いたもの)の中にが存在するかを調べればよい.
存在判定はでできるので全体の計算量はである.
提出:https://codeforces.com/contest/2037/submission/291961821
C - Superultra’s Favorite Permutation
問題概要
正の整数が与えられる.の順列であって,任意のに対してが合成数であるものが存在するか判定し,存在するならばひとつ出力せよ.
制約
考えたこと
こういうシンプルな発想力を要する問題は楽しい!
実は,が大きいとき条件を満たす順列は必ず構成できる.
まず,異なる正の奇数の和と異なる正の偶数の和はそれぞれ必ず偶数であり,しかもより大きいからこれは合成数である.よってを奇数どうし,偶数どうし連続させるとよさそうである.奇数と偶数の境界が問題となるが,でこれは合成数だから,境界ではを隣接させればよい.
したがってのときは「のうち奇数であるもの(以外)」,,「のうち偶数であるもの(以外)」を順に並べたものが条件を満たす順列になる.
のときはが小さいので通りを全探索しても間に合う.コンテスト中はこの方針で実装したが,よく考えるとのときに条件を満たす順列が存在しないことはちょっと考察すると分かるのでその必要はなかった.
提出:https://codeforces.com/contest/2037/submission/291983215
D - Sharky Surfing
問題概要
無限に長い数直線上を,Mualaniは以下の条件を満たしながら位置から位置まで移動する.
- はじめ,Mualaniは位置におり,Mualaniのジャンプ力はである.
- Mualaniが位置におり,ジャンプ力がであるとき,Mualaniはなる任意の整数の位置へ移動することができる.
- 個の閉区間で表される「ハードル」があり,この区間に属する座標には移動することができない.
- 個の座標があり,Mualaniは位置にいるときに自分のジャンプ力をだけ増加(パワーアップ)させることができる(しなくてもよい).この操作は各に対してそれぞれ回までしか行うことはできない.
このとき,Mualaniが回以上の移動を繰り返して位置に到達することが可能かどうかを判定し,可能である場合はパワーアップ回数の最小値を求めよ.
制約
- 任意のに対して
- となるは存在しない
考えたこと
はじめにDP方針をとって迷走してしまったが,実は貪欲に移動方法を選んでいくことができる.
まず,移動回数を最小化する必要はないから,基本的にはずつ移動するとしても損しない.しかし,ハードル上に移動することはできないから,長さのハードルを超えるためにはその直前までにジャンプ力を以上にしておく必要がある.
ここで,パワーアップが以下のような設定であるとしても答えは変わらない.
- 個の座標があり,Mualaniは位置にいるときに自分のジャンプ力をだけ増加させることができる(しなくてもよい).この操作は各に対してそれぞれ回までしか行うことはできない.
このような設定のもとでは,パワーアップは必要になったタイミング(=ハードルの直前)でまとめて行えばよい.さらに,パワーアップの選択肢が複数ある場合には,ジャンプ力の増分が最も大きいものを選ぶとしても損しない.
ここまで考えれば,以下のようなアルゴリズムによって貪欲に移動していくことができる.
- 現在実行可能なジャンプ力増加操作について,その増分を要素にもつような多重集合を,Mualaniの現在位置を,ジャンプ力を,ジャンプ力の増加操作回数をとする.
- はじめを空集合で,で初期化する.
- およびをまとめて昇順にソートし,順に以下を行う:
- ジャンプ力増加位置の場合:
- にを追加する.
- ハードルの場合:
- である限り以下を繰り返す.
- が空の場合は処理を終了する(このとき位置に到達することが不可能).
- そうでない場合,から最大の要素を取り出しおよびとする.
- である限り以下を繰り返す.
- 最終的なが求める最小の操作回数である.
として優先度付きキューを用いれば計算量はである.
提出:https://codeforces.com/contest/2037/submission/292010358
F - Ardent Flames
問題概要
整数が与えられる.数直線上に体の敵が並んでおり,敵の位置は,強さはである.
はじめに整数を選び固定する.このとき,以下の操作を回以上何回でも行うことができる.
- 操作:すべての敵をいっせいに攻撃する.この攻撃によって,位置にある敵の強さはだけ減少する.
体以上の敵の強さを以下にすることができるかを判定し,可能な場合は必要な操作回数の最小値を求めよ.
制約
考えたこと
二分探索まではすぐ見えたが判定関数の実装方針であらぬ方向に行ってしまい,コンテスト後にupsolveすることになった.
操作を回行うとして,以下のような判定問題に対して二分探索を行う.
- 判定問題:回の操作によって体以上の敵の強さを以下にすることができるか?
回の操作によって敵の強さが以下になるための必要十分条件は
である.だから,これはさらに
と同値である.これを変形すると
が得られる.このように,敵の強さを以下にすることのできるの範囲はある区間をなす.なお,は整数だから,上の区間は
としても同じことである.
よって,あとは以下の部分問題が解ければよい.
- 部分問題:個の閉区間が与えられる.整数を含むような区間が個以上存在するようなは存在するか?
これは,区間の座標を昇順にソートして区間の重なり数をシミュレーションすることでで判定可能である.
したがって,二分探索の上限をとしてもとの問題をで解くことができた.
提出(コンテスト後):https://codeforces.com/contest/2037/submission/292119997