基本情報技術者 2012年 秋期 午前(科目A) 問06
問題文
昇順に整列済みの配列要素A(1), A(2), ..., A(n)から、A()=となる配列要素A()の添字を2分探索法によって見つける処理を図に示す。終了時点で=0である場合は、A()=となる要素は存在しない。図中の[ a ]に入る式はどれか。ここで、“/“は、小数点以下を切り捨てる除算を表す。

選択肢
ア:
イ:(正解)
ウ:
エ:
2分探索での中央値計算式の決定【午前2 解説】
要点まとめ
- 結論:探索区間の中点を整数添字で取るため、(“/”は小数点以下切捨て)が正解です。
- 根拠:昇順配列の各反復で添字の中間を基準に比較し、区間を左右に半分に分割する処理だからです。
- 差がつくポイント:言語の整数除算やオーバーフローに注意し、実装では
(x+y)//2
か安全にx + (y-x)//2
を使うと良いです。
正解の理由
二分探索は現在の区間を左右それぞれほぼ同じ長さに分割して探索範囲を狭めます。区間の両端を (左端)、(右端)とすると、分割点は中点 です。与えられた図は中点で比較し、 が と等しければ終了、より大きければ右端を に、より小さければ左端を に更新する動作を示しています。したがって中点を求める式は小数切捨ての整数除算である
(図中の“/”が切捨てを意味)であり、選択肢では イ が該当します。
よくある誤解
- 「 ではなく をそのまま代入すればよい」という誤解:整数添字が必要なので中点を取らないと範囲が適切に狭まらない。
- 「(x-y)/2 や (y-x)/2 が中点」:これらは差の半分であり、左端や右端からのオフセットを表すが直接中点の添字にはならない。
- 実装上のオーバーフロー無視: が大きいと加算でオーバーフローする言語があるため、安全な計算式を知らないとバグになる。
解法ステップ
- 初期化:, 。
- ループ開始: を比較する判断に進む( なら存在しないとして 終了)。
- 中点計算:(小数切捨て)。
- 比較: と を比較する。
- の場合: を返して終了。
- の場合:右端を更新 。
- の場合:左端を更新 。
- ステップ2へ戻る。存在しなければ最終的に 。
# Python での典型的な中点計算(整数除算)
x, y = 1, n
while x <= y:
m = (x + y) // 2 # これが図の (x+y)/2(切捨て)
if A[m] == k:
return m
elif A[m] > k:
y = m - 1
else:
x = m + 1
# 見つからなければ return 0
選択肢別の誤答解説
- ア:
- 誤り。これは中点計算にならず、添字が区間の合計となって範囲縮小の意味を成しません。
- イ: $(x+y)/2→m
- 正解。区間の中点を整数添字で得る式で、図の動作(左右半分に分割)と一致します。
- ウ:
- 誤り。これは区間長の半分(左端との差)になるため、直接的に中点の添字にはならず誤用すると負や不正な添字になる可能性があります。
- エ:
- 誤り。上と同様に区間幅の半分を表すだけで、中点の絶対位置を示していません(左端を加味していない)。
補足コラム
- 実装上の注意点:C系言語などで
m = (x + y) / 2
をそのまま使うと整数のオーバーフローでバグになることがあります。安全な書き方はm = x + (y - x) / 2
(整数演算)またはm = x + (y - x) // 2
(Python)です。 - 中点の取り方には「下中点(floor)」と「上中点(ceil)」があり、境界処理やループ条件によって使い分けます。本問の流れ(, )は下中点を想定しています。
FAQ
Q1. 「/」が切捨てでなければどうなる?
A1. 小数を含むと添字は整数でないため意味を為しません。問題文の注記どおり切捨てが前提です。実装では整数除算(floor)を用いてください。
A1. 小数を含むと添字は整数でないため意味を為しません。問題文の注記どおり切捨てが前提です。実装では整数除算(floor)を用いてください。
Q2. 中点を
A2. 言語や値域によってはオーバーフロー回避のため後者が安全です。実装上の推奨は後者です。
(x+y)//2ではなく
x + (y-x)//2にするべき?
A2. 言語や値域によってはオーバーフロー回避のため後者が安全です。実装上の推奨は後者です。
Q3. 左閉区間・右閉区間の違いで中点の選び方は変わりますか?
A3. ループ条件や端点更新の仕方に応じて下中点/上中点を選ぶ必要があります。本問題では下中点(切捨て)で合っています。
A3. ループ条件や端点更新の仕方に応じて下中点/上中点を選ぶ必要があります。本問題では下中点(切捨て)で合っています。
関連キーワード: 二分探索、中央値計算、整数除算、床関数、添字操作、アルゴリズム、探索効率、境界処理

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

