残念ながらサーバートラブルの影響で今回はUnratedとなったようです。
もしRatedだったら、ABC帯の参加者にとっては、まさかの4完早解き競争になってた!?
各問題
A - Consecutive Integers
入出力例見るまで、問題の意味が頭に入ってきませんでした。酔いの影響か?
例えばN=8 K=3
なら
12345678 123 234 345 456 567 678
で6通りということですね。
B - RGB Boxes
これも問題の意味がすんなり頭に入ってきませんでした。やっぱり酔いの影響か?
二重ループを回してrとgを決めてから、それに対応するbが存在しうるかどうかを計算して求めれば間に合う典型のやつですね。
C - AB Substrings
- 各文字列中にある"AB"を数える
- 先頭の"B"と末尾の"A"を数えて、少ない方の数だけさらに"AB"が組めるので加算する
- ただし、「"B"ではじまり"A"で終わる」文字列以外に先頭の"B"と末尾の"A"が一つもなかった場合、組める数が一つ減る
- 循環してしまうので
- ただし、「"B"ではじまり"A"で終わる」文字列以外に先頭の"B"と末尾の"A"が一つもなかった場合、組める数が一つ減る
という感じです。
私は先頭の"B"と末尾の"A"が一つもなかった場合にも、組める数が一つ減るのロジックが働いてしまい、1WAを出してしまいました。 考察はあっているのに実装でミスるとは・・・。on_
D - DivRem Number
ロジック自体は極めて単純で、個人的には1012からいかに枝狩りできるかの問題でした。 なんか数学的にシンプルな解法があるんだろうなぁとは思いつつ。(editorialにはもちろんそのシンプルな解法が書いてありました。)
で、ちょっと考えてわからなかったので、とりあえず結果を全部出力してみます。
// N=1000の場合(抜粋) 125/ 8:0 126/ 7:118 127/ 7:111 128/ 7:104 129/ 7:97 130/ 7:90 131/ 7:83 132/ 7:76 133/ 7:69 134/ 7:62 135/ 7:55 136/ 7:48 137/ 7:41 138/ 7:34 139/ 7:27 140/ 7:20 141/ 7:13 142/ 7:6 143/ 6:142
商が同じになる範囲について、余りは大きい数字から始まり商の数だけ減少していくことがわかります。 なので、1から順に計算して、商が変わったタイミングで余りを商で割ってみて
- 割り切れた場合
- お気に入りの数がありかつそれは計算で求まるのでその数字まですっ飛ばすことができる
- 割り切れなかった場合
- お気に入りの数はないので、商が変わるところまですっ飛ばすことができる
という方法で、大幅に計算量を削減することができました。
可視化するとこんな感じです。
(前略) 126/ 7:118 // 118 % 7 != 0 なので商=6まで飛ぶ 143/ 6:142 // 142 % 6 != 0 なので商=5まで飛ぶ 167/ 5:165 // 165 % 5 == 0 なので N / x = 5 かつ N % x = 5 となる x まで飛ぶ 199/ 5:5 // x が求められているので、xを答えに加算して商=4になるところまで飛ぶ、でもいいですね 200/ 5:0 201/ 4:196 // 以下同様 249/ 4:4 250/ 4:0 251/ 3:247 334/ 2:332 499/ 2:2 500/ 2:0 501/ 1:499 999/ 1:1 2257
まとめ
考察してわからなかったら実際にやってみるが重要だった回。
Unratedになったのは残念でしたが(個人的にはパフォ自己べを余裕で更新していたっぽいのでなおさら)、まあこんなときもありますよね。