A - 訓練メニューの消化 / Completing the Training Menu 解説 by admin
GPT 5.2 High概要
各エクササイズを何回選べるかを数え上げ、合計で \(M\) 回のトレーニングが可能かを判定する問題です。
考察
1回のトレーニングでは、選んだエクササイズの残り回数が ちょうど \(K\) 減る ので、エクササイズ \(i\) を選べる回数は
- \(A_i \ge K\) の間だけ選べる
- 選ぶたびに \(K\) ずつ減る
ということから、最大で [ \left\lfloor \frac{A_i}{K} \right\rfloor ] 回です。
ここで重要なのは、どの順番でエクササイズを選んでも「可能な総トレーニング回数」は変わらないことです。なぜなら、各エクササイズは独立に「\(K\) を何回引けるか」だけで上限回数が決まるからです。
素朴に「\(M\) 日ぶんを1日ずつシミュレーションする」方法は、\(M \le 10^9\) なので最悪 \(10^9\) 回の処理になり、時間的に間に合いません(TLEの原因)。
そこで、各 \(i\) について \(\left\lfloor A_i/K \right\rfloor\) を足し合わせ、その合計が \(M\) 以上かどうかだけを見ればよいです。
例えば \(K=3,\ A=[7,2,8]\) のとき
- \(7//3=2\) 回
- \(2//3=0\) 回
- \(8//3=2\) 回
合計 \(4\) 回できるので、\(M \le 4\) なら Yes になります。
アルゴリズム
- 入力として \(N,M,K\) と配列 \(A\) を受け取る。
- カウンタ
cnt=0を用意する。 - 各 \(a \in A\) について
cnt += a // Kを行う(そのエクササイズで可能な回数を加算)。 cnt >= Mになった時点でYesを出力して終了(早期終了)。- 最後まで足しても
cnt < MならNoを出力。
計算量
- 時間計算量: \(O(N)\)
- 空間計算量: \(O(1)\)(※入力配列を除く。配列を保持するなら \(O(N)\))
実装のポイント
可能回数は必ず整数なので、
a // K(切り捨て除算)を使います。cntが \(M\) に到達したら、それ以上計算する必要がないため早期終了すると高速です。\(A_i, K, M\) は最大 \(10^9\) ですが、合計は最大で \(N \times 10^9\) 程度になり得ます。Python の整数はオーバーフローしないので安心して加算できます。
ソースコード
import sys
def main():
input = sys.stdin.readline
N, M, K = map(int, input().split())
A = list(map(int, input().split()))
cnt = 0
for a in A:
cnt += a // K
if cnt >= M:
print("Yes")
return
print("No")
if __name__ == "__main__":
main()
この解説は gpt-5.2-high によって生成されました。
投稿日時:
最終更新: