AtCoder Beginner Contest 195のきろく

パナソニックプログラミングコンテスト(AtCoder Beginner Contest 195)でレートを冷やしてしましました...

A - Health M Death (100点)

そのままif文で処理します。C/C++int型をそのまま突っ込めるので突っ込みます(その必要はない)。

B - Many Oranges (200点)

x 個のみかんを選んで重さの合計がちょうど W となったとすると Ax \leq 1000W \leq Bx より \displaystyle \frac{1000W}{B} \leq x \leq \frac{1000W}{A}x は整数より \displaystyle \left\lceil \frac{1000W}{B} \right\rceil \leq x \leq \left\lfloor \frac{1000W}{A} \right\rfloor です。
a,\,b が正整数の時 \displaystyle \left\lceil \frac{a}{b} \right\rceil = \left\lfloor \frac{a + b - 1}{b} \right\rfloor であることから整数で計算できます。

上限と下限の大きさが反転しているときこのような x は存在しないと判定できます。

C - Comma (300点)

10^{3i} \leq N のとき右から i 番目のコンマは 10^{3i} から N までの N - 10^{3i} + 1 個の数字で用いるのでその和をとります。

D - Shipping Center (400点)

この問題で色々詰まってしまいました。最終的には解けたのですが終了後にもっと効率の良い実装を思いつきました。

i と 箱j について それぞれの箱に入れることのできる荷物の集合を B_i,\,B_j とし、X_i \leq W_i とすると B_i \subseteq B_j となるので、クエリ毎に、小さな箱から順に、その時点でその箱に入れることができる価値最大の荷物を入れていくことで最大値を得ることができます。
ここで「その時点でその箱に入れることができる価値最大の荷物」は 荷物を Wを基準としてソート*1することで尺取り法で優先度付きキューに V の値を入れていくことで求めることができます。

E - Lucky 7 Battle (500点)

ゲームDPだとは思っていたのですが、Dを通すのが遅れたため、あまり考察できず時間内には通すことができませんでした。DPで各状態において値をどうすればいいかについて考えていました。集合が思いつきかけたので辛い...

{\mathrm{dp}}_i = (\text{\(i\) ラウンド終了時の \(T\bmod{7}\) の値で、高橋くん必勝となる値の集合})
とすると自明に {\mathrm{dp}}_N = \{0\} であり、各ターン高橋くんは {\mathrm{dp}}_{i+1} に属す状態に動ける場合そちらに動こうとし、青木君は{\mathrm{dp}}_{i+1} に属さない状態に動ける場合そちらに動こうとします。そのため
$$
{\mathrm{dp}}_{i+1} = \left\{
\begin{array}{ll}
\{n \mid 10n\bmod{7} \in {\mathrm{dp}}_i \lor (10n + S_i)\bmod{7} \in {\mathrm{dp}}_i \} & (X_i = \texttt{`T'})\\
\{n \mid 10n\bmod{7} \in {\mathrm{dp}}_i \land (10n + S_i)\bmod{7} \in {\mathrm{dp}}_i \} & (X_i = \texttt{`A'})
\end{array}
\right.
$$
となり、(0 \in {\mathrm{dp}}_0\, ?\, 高橋くん : 青木くん ) の勝ちとなります。
この \mathrm{dp}std::setを要素とする配列、bitによる集合を要素とする配列、2次元配列等として実装できます。

F - Digits Paradise in Hexadecimal (600点): 未提出

素数ごとに考えるのかなぁってぐらいしか思いついてないです...

結果、感想

f:id:Flkanjin:20210314005910p:plain
前回折角1700超えたのに... 次は恢復できるよう頑張ります

*1:W の値でソート。W が等しい要素については V の値でソート