B - クラス委員長の選出 / Election of the Class President 解説 by admin
Claude 4.5 Opus概要
現在の委員長(出席番号1の生徒)よりもリーダーシップ点数が高い生徒の中から、最も点数が高く、同点なら出席番号が最も小さい生徒を見つける問題です。
考察
重要な気づき
比較対象は出席番号2以降の生徒のみ: 出席番号1の生徒は現在の委員長なので、それ以外の生徒から候補を探します。
2段階の条件がある:
- まず、現在の委員長の点数 \(A_1\) より真に大きい点数を持つ生徒だけが候補
- その候補の中で、最大点数の生徒を選ぶ
- 最大点数が同じ生徒が複数いれば、出席番号が小さい方を選ぶ
候補がいない場合は -1 を出力: 現在の委員長以上に点数が高い生徒がいなければ変更は行われません。
具体例
例えば、\(N = 5\)、\(A = [50, 80, 80, 90, 70]\) の場合: - 現在の委員長は出席番号1(点数50) - 点数50より大きい生徒: 出席番号2(80), 3(80), 4(90), 5(70) - この中で最大点数は90(出席番号4) - よって、答えは 4
別の例で、\(N = 3\)、\(A = [100, 50, 30]\) の場合: - 現在の委員長は出席番号1(点数100) - 点数100より大きい生徒: いない - よって、答えは -1
アルゴリズム
- 現在の委員長のリーダーシップ点数 \(A_1\) を記録する
- 出席番号2から\(N\)までの生徒を順番に調べる
- 各生徒について:
- 点数が \(A_1\) より大きいかチェック
- 大きい場合、これまでの最大点数と比較
- より大きければ、最大点数と出席番号を更新
- 同じ点数なら、出席番号が小さい方を保持
- 最終的に候補が見つかれば出席番号を、見つからなければ -1 を出力
現在の委員長の点数 = A[0]
最大点数 = -1
答えの出席番号 = -1
for i = 1 to N-1:
if A[i] > 現在の委員長の点数:
if A[i] > 最大点数:
最大点数 = A[i]
答えの出席番号 = i + 1 # 0-indexedなので+1
elif A[i] == 最大点数:
# 出席番号が小さい方を選ぶ(先に見つかった方が小さい)
# この実装では左から順に見るので自動的に小さい方が保持される
計算量
- 時間計算量: \(O(N)\)
- 配列を1回走査するだけで答えが求まります
- 空間計算量: \(O(N)\)
- 入力配列を保持するための空間
実装のポイント
0-indexed と 1-indexed の変換: 配列は0-indexedで管理しますが、出席番号は1-indexedなので、出力時に
i + 1とする必要があります。同点の場合の処理: 左から順に走査しているため、同じ点数の生徒が見つかったとき、先に見つかった方(出席番号が小さい方)を保持し続ければよいです。コードでは
A[i] == max_scoreの場合にi + 1 < max_indexをチェックしていますが、左から順に見ているので実際にはこの条件が真になることはありません(より簡潔に書くなら省略可能)。初期値の設定:
max_score = -1としておくことで、点数が1以上という制約の下、正しく動作します。ソースコード
N = int(input())
A = list(map(int, input().split()))
current_leader_score = A[0]
max_score = -1
max_index = -1
for i in range(1, N):
if A[i] > current_leader_score:
if A[i] > max_score:
max_score = A[i]
max_index = i + 1
elif A[i] == max_score:
if i + 1 < max_index:
max_index = i + 1
if max_index == -1:
print(-1)
else:
print(max_index)
この解説は claude4.5opus によって生成されました。
投稿日時:
最終更新: