2024-08-11
AtCoder Beginner Contest 365に参加した
ABC365の参加記.
8月3日に開催されたトヨタ自動車プログラミングコンテスト2024#8(AtCoder Beginner Contest 365)に参加した.ABCDEの5完で509位.
A - Leap Year
西暦年の日数を答える問題.要するにうるう年かどうかが判定できればよく,うるう年の判定条件は問題文で与えられているので言われた通り実装する.
提出:https://atcoder.jp/contests/abc365/submissions/56238645
B - Second Best
長さの数列が与えられるので,の中で2番目に大きい要素のインデックスを求める問題.
Rustだとsorted_by_keyを使ってイテレータ0..nをソートするのが楽かも.
提出:https://atcoder.jp/contests/abc365/submissions/56238645
C - Transportation Expenses
整数と数列が与えられるとき,
を満たす最大の整数を求める問題.ストーリーは「の人に交通費円を支給するとき,予算円を超えないように1人あたりの支給上限額をどこまで大きくできるか?」というもの.
まず,上限額なしでも予算内に収まる場合(のとき)は最大値が存在しない.そうでない場合はの範囲に最大値が存在するので二分探索する.
二分探索パートは、判定関数f,探索範囲[ok, ng)(または(ng, ok])を渡すようなライブラリを事前に作っておくとバグりにくい.なお探索範囲の下限・上限ではなくtrue側の端点・false側の端点を渡すのはいわゆる「めぐる式」の実装である(出典).
提出:https://atcoder.jp/contests/abc365/submissions/56253079
D - AtCoder Janken 3
2人でじゃんけんを回する.相手が出す手が分かっているとき,直前と同じ手を出すことはできないという条件のもとで自分は最大何回勝つことができるか? という問題.
これは以下のような値を更新していくDPで解くことができる.
- :番目の試合までみたとき,直前に出した手がであるときの勝った回数の最大値
同じ手は連続して出せないので,から遷移できるのはである.
実装上は,R, P, Sをに対応させるなどすると勝利判定が少し楽になる.実際
- 手が手に勝つ
なので面倒な場合分けが最小限で済む.
提出:https://atcoder.jp/contests/abc365/submissions/56260604
E - Xor Sigma Problem
長さの整数列が与えられるので,幅2以上のすべての区間に対する区間XORの総和
を求める問題.
定石に従い,桁ごとに考えて最後にそれぞれの項の和への寄与を足しあげることにする(桁目には係数としてがかかる).bitwise XORの定義から,の桁目というのはの桁目にが奇数個あれば,偶数個あればになる.
よって,長さの01列の中で奇数個のを含むような区間を数え上げればよく,これは累積和をで構築し値が異なるペアを数えればOK(01列に対して,が奇数個のを含む 累積和をとしたときが奇数).最後に幅1の区間を計算結果から除外することを忘れない.