A - 最適な練習相手 / Optimal Practice Partner 解説 by admin
Claude 4.5 Opus概要
高橋君が勝てる部員(実力値が \(L\) 以下の部員)の中で、最も実力値が高い部員の番号を求める問題です。
考察
問題を解くための重要な気づき
この問題では、以下の2つの条件を満たす部員を探す必要があります: 1. 勝てる条件: \(D_i \leq L\) を満たす(高橋君の実力値以下) 2. 最適な相手: 条件1を満たす中で、\(D_i\) が最大の部員 3. タイブレーク: \(D_i\) が同じ場合は、部員番号が最も小さい部員
具体例で考える
例えば、\(N = 5\)、\(L = 100\) で、各部員の実力値が \(D = [80, 120, 100, 100, 50]\) の場合: - 部員1: \(D_1 = 80 \leq 100\) → 勝てる ✓ - 部員2: \(D_2 = 120 > 100\) → 勝てない ✗ - 部員3: \(D_3 = 100 \leq 100\) → 勝てる ✓ - 部員4: \(D_4 = 100 \leq 100\) → 勝てる ✓ - 部員5: \(D_5 = 50 \leq 100\) → 勝てる ✓
勝てる部員は {1, 3, 4, 5} で、その中で実力値が最大なのは部員3と部員4(どちらも100)です。番号が小さい方を選ぶので、答えは 部員3 となります。
アプローチの検討
- 素朴なアプローチ: 全部員を順番に見て、条件を満たす最大値を持つ部員を探す
- このアプローチで十分効率的(\(O(N)\))なので、特別な工夫は不要です
アルゴリズム
変数
best_index(答えとなる部員番号)とbest_value(その部員の実力値)を初期化するbest_index = -1(勝てる部員がいない場合の答え)best_value = -1(まだ候補がいない状態)
部員を番号1から順番に調べる(配列のインデックスでは0から)
各部員 \(i\) について:
- \(D_i \leq L\) かつ \(D_i > \text{best\_value}\) なら、その部員を新しい候補として記録
- ここで「より大きい(
>)」という条件を使うことで、同じ実力値の場合は先に見つけた(番号が小さい)部員が優先される
最終的な
best_indexを出力する
計算量
- 時間計算量: \(O(N)\)
- すべての部員を1回ずつ確認するため
- 空間計算量: \(O(N)\)
- 入力を格納する配列のサイズ
実装のポイント
1-indexedへの変換: 問題では部員番号は1から始まるが、配列のインデックスは0から始まる。そのため、答えを出力する際に
i + 1とする必要がある。タイブレークの処理: 同じ実力値の部員が複数いる場合、番号が小さい方を選ぶ。これは「より大きい(
>)」という厳密な不等号を使うことで自然に実現できる。最初に見つけた部員が記録され、同じ値の後続の部員では更新されない。勝てる部員がいない場合:
best_indexを-1で初期化しておけば、条件を満たす部員が1人もいなかった場合に自動的に-1が出力される。ソースコード
N, L = map(int, input().split())
D = list(map(int, input().split()))
best_index = -1
best_value = -1
for i in range(N):
if D[i] <= L:
if D[i] > best_value:
best_value = D[i]
best_index = i + 1 # 1-indexed
print(best_index)
この解説は claude4.5opus によって生成されました。
投稿日時:
最終更新: