2024-11-18

Codeforces Round 988 (Div. 3)に参加した

競プロアルゴCodeforces

Codeforces Div. 3の参加記.

11月17日に開催されたCodeforces Round 988 (Div. 3)に参加し,ABCDの4完で2304位だった.

久しぶりに出たら大失敗回になってしまって悲しい.Eを飛ばしてFに行ったら変な沼にはまった.

A - Twice

問題概要

問題文

長さnnの数列a=(a1,,an)a=(a_1,\cdots, a_n)が与えられる.この数列に対し,ai=aja_i=a_jであるような異なる要素ai,aj  (i<j)a_i, a_j\;(i < j)を選んで削除するという操作は最大で何回行うことができるか?

制約

考えたこと

数列aaの中にai=xa_i=xであるような要素がちょうどcxc_x個あったとすると,その要素からはcx/2\lfloor c_x/2\rfloor回の操作をすることができ,それ以上の回数の操作はできない.よって答えは

x=1ncx\sum_{x=1}^n c_x

である.

提出:https://codeforces.com/contest/2037/submission/291949756

B - Intercepted Inputs

問題概要

問題文

長さkkの数列a=(a1,,ak)a=(a_1,\cdots,a_k)が与えられる.正の整数n,mn, mであって以下の条件を満たすものをひとつ出力せよ.

制約

考えたこと

要素数の関係から,n,mn, mkkの間にはnm+2=knm+2=kという等式が成り立つ.

nnの候補を全探索する.n=ain=a_iであると仮定すると,k2k-2nnの倍数ならばm=(k2)/nm=(k-2)/nと決まる.よってあとは数列aa(からaia_iを除いたもの)の中にmmが存在するかを調べればよい.

存在判定はO(1)O(1)でできるので全体の計算量はO(k)O(k)である.

提出:https://codeforces.com/contest/2037/submission/291961821

C - Superultra’s Favorite Permutation

問題概要

問題文

正の整数nnが与えられる.1,,n1,\cdots, nの順列p=(p1,,pn)p=(p_1,\cdots,p_n)であって,任意のi=1,,n1i=1,\cdots, n-1に対してpi+pi+1p_i+p_{i+1}が合成数であるものが存在するか判定し,存在するならばひとつ出力せよ.

制約

考えたこと

こういうシンプルな発想力を要する問題は楽しい!

実は,nnが大きいとき条件を満たす順列は必ず構成できる.

まず,異なる正の奇数の和と異なる正の偶数の和はそれぞれ必ず偶数であり,しかも22より大きいからこれは合成数である.よって1,,n1,\cdots, nを奇数どうし,偶数どうし連続させるとよさそうである.奇数と偶数の境界が問題となるが,4+5=9=3×34+5=9=3\times 3でこれは合成数だから,境界では4,54, 5を隣接させればよい.

したがってn5n\geq 5のときは「1,,n1,\cdots,nのうち奇数であるもの(55以外)」,5,45, 4,「1,,n1,\cdots,nのうち偶数であるもの(44以外)」を順に並べたものが条件を満たす順列になる.

n<5n<5のときはnnが小さいのでn!n!通りを全探索しても間に合う.コンテスト中はこの方針で実装したが,よく考えるとn<5n<5のときに条件を満たす順列が存在しないことはちょっと考察すると分かるのでその必要はなかった.

提出:https://codeforces.com/contest/2037/submission/291983215

D - Sharky Surfing

問題概要

問題文

無限に長い数直線上を,Mualaniは以下の条件を満たしながら位置11から位置LLまで移動する.

このとき,Mualaniが00回以上の移動を繰り返して位置LLに到達することが可能かどうかを判定し,可能である場合はパワーアップ回数の最小値を求めよ.

制約

考えたこと

はじめにDP方針をとって迷走してしまったが,実は貪欲に移動方法を選んでいくことができる.

まず,移動回数を最小化する必要はないから,基本的には11ずつ移動するとしても損しない.しかし,ハードル上に移動することはできないから,長さddのハードルを超えるためにはその直前までにジャンプ力をd+1d+1以上にしておく必要がある.

ここで,パワーアップが以下のような設定であるとしても答えは変わらない.

このような設定のもとでは,パワーアップは必要になったタイミング(=ハードルの直前)でまとめて行えばよい.さらに,パワーアップの選択肢が複数ある場合には,ジャンプ力の増分が最も大きいものを選ぶとしても損しない.

ここまで考えれば,以下のようなアルゴリズムによって貪欲に移動していくことができる.

  1. 現在実行可能なジャンプ力増加操作について,その増分を要素にもつような多重集合をSS,Mualaniの現在位置をxx,ジャンプ力をpp,ジャンプ力の増加操作回数をcnt{\rm cnt}とする.
  2. はじめSSを空集合で,x1x\leftarrow 1で初期化する.
  3. x1,,xmx_1,\cdots, x_mおよびl1,,lnl_1,\cdots, l_nをまとめて昇順にソートし,順に以下を行う:
  1. 最終的なcnt{\rm cnt}が求める最小の操作回数である.

SSとして優先度付きキューを用いれば計算量はO((n+m)log(n+m))O((n+m)\log (n+m))である.

提出:https://codeforces.com/contest/2037/submission/292010358

F - Ardent Flames

問題概要

問題文

整数n,m,kn, m, kが与えられる.数直線上にnn体の敵が並んでおり,敵iiの位置はxix_i,強さはhih_iである.

はじめに整数ppを選び固定する.このとき,以下の操作を00回以上何回でも行うことができる.

kk体以上の敵の強さを00以下にすることができるかを判定し,可能な場合は必要な操作回数の最小値を求めよ.

制約

考えたこと

二分探索まではすぐ見えたが判定関数の実装方針であらぬ方向に行ってしまい,コンテスト後にupsolveすることになった.

操作をcc回行うとして,以下のような判定問題に対して二分探索を行う.

cc回の操作によって敵iiの強さが00以下になるための必要十分条件は

c×max(0,mpxi)hic\times \max (0, m-|p-x_i|)\geq h_i

である.hi>0h_i > 0だから,これはさらに

c(mpxi)hic(m-|p-x_i|)\geq h_i

と同値である.これを変形すると

xi+hicmpxihic+mx_i+\frac{h_i}{c}-m\leq p\leq x_i-\frac{h_i}{c}+m

が得られる.このように,敵iiの強さを00以下にすることのできるppの範囲はある区間をなす.なお,ppは整数だから,上の区間は

xi+hicmpxihic+mx_i+\left\lceil\frac{h_i}{c}\right\rceil-m\leq p\leq x_i-\left\lceil\frac{h_i}{c}\right\rceil+m

としても同じことである.

よって,あとは以下の部分問題が解ければよい.

これは,区間の座標を昇順にソートして区間の重なり数をシミュレーションすることでO(nlogn)O(n\log n)で判定可能である.

したがって,二分探索の上限をcmaxc_{\rm max}としてもとの問題をO(nlognlogcmax)O(n\log n\log c_{\rm max})で解くことができた.

提出(コンテスト後):https://codeforces.com/contest/2037/submission/292119997