2023-07-18

AtCoder Beginner Contest 310に参加した

競プロアルゴAtCoder

ABC310の参加記.

7月15日に開催されたfreee プログラミングコンテスト2023(AtCoder Beginner Contest 310)に参加した.ABCDEの5完で541位,復帰後はじめてレートが上がった.

A - Order Something Else

問題文

定価PP円の商品があり,定価で買うか,割引券を使ってQQ円で買う代わりに他の商品を追加で買うかの2種類の選択肢がある.他の商品はNN種類あって商品iiの値段がDiD_i円であるとき,支払う金額を最小化する問題.

割引券を使う場合は最も安い商品を選べばよく,そもそも定価で買ったほうが安い場合は割引券を使う必要がない.よってmin(P,Q+Dmin){\rm min}(P, Q+D_{\rm min})が答え.

提出:https://atcoder.jp/contests/abc310/submissions/43582896

B - Strictly Superior

問題文

NN個の要素からなる数列P=(Pi)P=(P_i)および集合の列F=(Fi)F=(F_i)が与えられるので,ある条件を満たすような1i,jN1\leq i,j\leq Nが存在するかを判定する問題.

制約が小さいので愚直に条件をチェックするだけだが,条件の内容がやっかいで実装が大変だった.条件の形が「AかつBかつC」のような形になっているので,「Aでない場合はcontinueして次のループへ移動する」という実装にすると比較的楽……と思いきや,Aの否定を考えるのが面倒.「任意の○について△」の否定は「ある○が存在して△でない」になることなどを頭の片隅に呼び出しつつ,頑張った.

提出:https://atcoder.jp/contests/abc310/submissions/43590208

C - Reversible

問題文

英小文字からなる文字列がNN個与えられる.文字列を逆順に読んで一致するものを区別しないとき,異なる文字列は何個あるか? という問題.

文字列を順に走査しながら,すでに出現した文字列の集合を更新していく.文字列SSが登場したとき,SSだけではなくSSを逆から読んだ文字列も集合に追加することにすれば,最終的に集合の要素数の半分が答えになる.

ただし,上のアルゴリズムは回文があるときに壊れるので,回文がきたときには回文にならないように適当な文字(英小文字以外ならなんでもいい)を末尾に挿入してから集合に放り込む.

提出:https://atcoder.jp/contests/abc310/submissions/43592997

D - Peaceful Teams

問題文

区別のつくNN人を区別できないTTチームに分ける方法を答える問題.ただし,「相性の悪い」ペアがMM組あり,各ペアについて,2人は別のチームに入れなければならない.

制約が1TN101\leq T\leq N\leq 10と小さいので全探索ができそう.ざっくり状態数を見積もると,NN人それぞれに対してどのチームに入れるかがTT通りあるから大体NTN^T通りとなって,最大で101010^{10}程度になる? 実行時間制限に間に合わないじゃんと一瞬思うが,チームは区別しないので実際にはNT/T!N^T/T!程度にしかならないことに気づく.結局全探索で良さそう.

「何人目まで決めたか」と「チーム割り当て」を状態に持ちながらDFSをすればよいが,重複をせずに数え上げるのが少し面倒.実装の便宜上チームに番号を割り当てたいが,重複があってはいけないので「まだ誰もいないチームに新たに人を割り当てるときには,まだ使われていない番号のうち最小となるように付番する」ことに気をつける.

提出:https://atcoder.jp/contests/abc310/submissions/43602429

E - NAND repeatedly

問題文

0011からなる数列A=(Ai)A=(A_i)が与えられるので,区間[l,r)[l,r)に対してAl,,Ar1A_l,\cdots, A_{r-1}の累積NANDを計算したものを,すべてのl,rl,rの組について足し合わせたものを求める問題.ただしNANDは結合則を満たさないので,計算は左から行うとする.

愚直に計算するとΩ(N2)\Omega (N^2)かかってしまうので高速化する方法を考える.よく考えると,区間NANDを計算していく過程で,次の値は直前の値だけで決まる.よって,

というDPテーブルを更新していくことができ,最終的な答えは

idp[i][1]\sum_i {\rm dp}[i][1]

となる.

jjのとりうる値は0011しかないので状態数はO(N)O(N),遷移はO(1)O(1)なので全体として計算量はO(N)O(N)になって間に合う.

提出:https://atcoder.jp/contests/abc310/submissions/43617977