基本情報技術者試験 科目B サンプル問題 問4の解説|引き算をくり返して最大公約数を求める gcd

基本情報技術者試験

科目B サンプル問題 問4難易度 ★擬似言語・while と if・最大公約数最終更新 2026-09-22

どの行が何をしているかをつかめば、空欄は3つとも決まります。

難易度 ★(当サイトの目安)── 説明文の(1)〜(3)を while と if に写すだけ。4段階の決め方は科目B 最短合格の戦略にあります。

出題

出典:基本情報技術者試験 科目B サンプル問題 問4

次のプログラム中の  a  ~  c  に入れる正しい答えの組合せを,解答群の中から選べ。

関数gcd は,引数で与えられた二つの正の整数num1 とnum2 の最大公約数を,次の(1)~(3) の性質を利用して求める。

(1) num1 とnum2 が等しいとき,num1 とnum2 の最大公約数はnum1 である。

(2) num1 がnum2 より大きいとき,num1 とnum2 の最大公約数は,(num1 - num2) とnum2 の最大公約数と等しい。

(3) num2 がnum1 より大きいとき,num1 とnum2 の最大公約数は,(num2 - num1) とnum1 の最大公約数と等しい。

〔プログラム〕

○整数型: gcd(整数型: num1, 整数型: num2)
  整数型: x ← num1
  整数型: y ← num2
   a 
    if ( b )
      x ← x - y
    else
      y ← y - x
    endif
   c 
  return x

解答群

ア a = if (x ≠ y) / b = x < y / c = endif

イ a = if (x ≠ y) / b = x > y / c = endif

ウ a = while (x ≠ y) / b = x < y / c = endwhile

エ a = while (x ≠ y) / b = x > y / c = endwhile

※ 解答群の原本は a・b・c を3つの列に分けた表です。当サイトでは1行にまとめて引用しました(字句は変えていません)。

答えだけ先に見る

正解は エ(a = while (x ≠ y)/b = x > y/c = endwhile)です。

この問題に出てくる記号

読めない記号があったときだけ開いてください。

擬似言語の記号 5コ の読み方をひらく
書き方 読み方
整数型: x ← num1 整数の箱 x を用意して、num1 の値を入れる
x ← x - y x から y を引いた値で、x を上書きする
if (…) / else / endif かっこの中が真なら上を、偽なら else の下を、1回だけ実行する
while (…) / endwhile かっこの中が真のあいだ、あいだの行を何度でもくり返す。偽になったら endwhile の次へ
x ≠ y x と y が等しくないとき真

コードは何をしているか ── 3つの性質が、コードのどこにあるか

見えている行が、問題文の性質(1)〜(3)のどれにあたるかを結びつけます。

○整数型: gcd(整数型: num1, 整数型: num2)

2つの正の整数を受け取る

整数型: x ← num1

num1・num2 を x・y に写す。以後は x・y がその役を引き継ぐ

整数型: y ← num2

 

 a 

?

if ( b )

?

x ← x - y

性質(2) x から y を引く = (num1 - num2) の形

else

 

y ← y - x

性質(3) y から x を引く = (num2 - num1) の形

endif

 

 c 

?

return x

性質(1) 等しいなら、x が答え

※ 右側の注釈は当サイトで書き加えたものです。プログラム自体は原文のまま引用しています。

関数 gcd が返すのは x です。だから、最後の x が最大公約数になっていなければなりません。そして性質(2)(3)のとおり、大きいほうから小さいほうを引いても、最大公約数は変わりません。つまりこのコードは、最大公約数を変えないまま引き算で2つの数を小さくしていき、x そのものが最大公約数になったところで返します。空欄で決めるのは、引き算の4行を何回実行するか(a・c)と、どちらが大きいときに x から引くか(b)です。

空欄 a と c を決める ── 1回引いたら終わりか

〔プログラム〕空欄 a〜c のまわり(上の〔プログラム〕から抜き出した。1字も変えていない)

  整数型: y ← num2
   a 
    if ( b )
      x ← x - y
    else
      y ← y - x
    endif
   c 
  return x

※ 上の〔プログラム〕からの抜粋です(1字も変えていません)。

return x が最大公約数になるのは、性質(1)のx と y が等しいときだけです。15 と 6 なら、9 と 6 → 3 と 6 → 3 と 3 と、3回引いてやっと等しくなります。だから、等しくなるまで引き算をくり返します。

もし a が if (x ≠ y) だったら

琥珀=書き換わった変数

15 と 6 で1回だけ引いて、そのまま return x(b は x > y のままとする)

前

x15

y6

後

x9

y6

if は1回だけ。9 と 6 のまま endif を抜けて、9 を返してしまいます。6 は 9 で割り切れないので、9 は最大公約数ではありません。b が逆向きでも、if なら1回で終わるのは同じです。

条件が真のあいだくり返すのが while です。a = while (x ≠ y)、c = endwhile。

空欄 b を決める ── どちらから引くか

〔プログラム〕空欄 b の if(上の〔プログラム〕から抜き出した。1字も変えていない)

    if ( b )
      x ← x - y
    else
      y ← y - x
    endif

※ 上の〔プログラム〕からの抜粋です(1字も変えていません)。

b が真のときに実行するのは x ← x - y。性質(2)の引き算で、使えるのは「num1 がnum2 より大きいとき」です。だから b = x > y。

もし b が x < y だったら

琥珀=書き換わった変数

15 < 6 は偽 → else で y から x を引く(a は while (x ≠ y) のままとする)

      y ← y - x

前

x15

y6

後

x15

y-9

小さいほうから大きいほうを引いて、6 - 15 = -9。次も 15 < -9 は偽なので、y は -24、-39 … と減り続け、x と y は等しくならず、くり返しが終わりません(答えが返りません)。

解答群を見る

a = while (x ≠ y)、b = x > y、c = endwhile。この組は エ です。

答え合わせ

正解は エ です。

ア・イは if なので1回で終わり、ウは向きが逆で終わりません。エを入れて gcd(15, 6) を最後まで動かすと、3 が返ります。

1行ずつ追う 正解の エ で gcd(15, 6)

出典:科目B サンプル問題 問4(空欄に エ を入れたもの)


ループ開始前

いま計算していること

まだ計算していません

変数の状態

トレース表(進めると1行ずつ積み上がります)

次に読む

この問題でどこに手間取ったかで、行き先が変わります。

この記事で引用した資料

いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。

Copied title and URL