09 過去問演習ー4(全分野 横断・4周目)

全10問。1〜3周目とは別の問題です。

配列問1 ★10進数を2進数に変換する流れ図

過去問(配列)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2020-12-13 問1〕
解説を表示

正解:エ

この問題は「10進数を2進数に直す筆算」を、そのまま流れ図にしたものです。まずは手で計算するやり方を思い出しましょう。

10進数を2進数にするときは、2で割った余りを下から順に並べるのでしたね。たとえば13なら:

わり算商(j div 2余り(j mod 2
13 ÷ 261
6 ÷ 230
3 ÷ 211
1 ÷ 201

出てきた余りを下から読むと 1101。これが13の2進数です。ここで大事なのは、最初に出た余りが2進数のいちばん下の桁(1の位)だということ。問題文でも「2進数は下位桁から順に NISHIN(1) から格納される」と書かれていて、この筆算の順番とぴったり一致します。

流れ図と筆算を対応させる

ループは k : 1, 1, 8、つまり k が1から8まで1ずつ増えながら8回まわります。1回のループで「1桁分」を作るわけです。1回のループの中でやるべきことは2つだけ:

  1. 余りを取り出して配列にしまうNISHIN(k) ← j mod 2
  2. 次の桁のために j を2で割った商に更新するj ← j div 2

この2つが a と b に入ります。ということは、問題は「どっちを先にやるか」だけです。

順番がひっくり返るとどうなるか(ここが最大のポイント)

j ← j div 2 を先にやってしまうと、j の中身が書き換わってしまいます。その後で j mod 2 を計算しても、それはもう「元の j の余り」ではなく「割った後の j の余り」=ひとつ先の桁の値になってしまいます。j = 13 で実際に確かめてみましょう。

正しい順(余り→商)逆の順(商→余り)
1回目NISHIN(1)=13 mod 2=1、j は 6 へj が 6 へ、NISHIN(1)=6 mod 2=0
2回目NISHIN(2)=6 mod 2=0、j は 3 へj が 3 へ、NISHIN(2)=3 mod 2=1
3回目NISHIN(3)=3 mod 2=1、j は 1 へj が 1 へ、NISHIN(3)=1 mod 2=1
4回目NISHIN(4)=1 mod 2=1、j は 0 へj が 0 へ、NISHIN(4)=0 mod 2=0
結果00001101 = 13 ✔00000110 = 6 ✘

逆順だと、いちばん下の桁(1の位)がまるごと消えて、答えが「13を2で割った6」になってしまいました。だから a に NISHIN(k) ← j mod 2、b に j ← j div 2 の エ が正解です。

ほかの選択肢がダメな理由

速解法

この形の問題は、選択肢を全部トレースする必要はありません。次の2段階でふるいにかけます。

  1. 「配列に入るのは余り、変数を更新するのは商」と決める。これで イ と ウ が即消えます(jmod を代入している時点でアウト)。
  2. 残った ア と エ は順番違いだけ。「保存してから壊す」が鉄則なので、余りを配列にしまう方が先 → エ。

合言葉は「取ってから割る」。使う予定の値を、使う前に上書きしてはいけない――これは流れ図の穴埋め問題で何度も出てくる考え方なので、覚えておくと得です。

スタック問2 ★逆ポーランド記法と計算式の対応

過去問(スタック)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2021-01-24 問6〕
解説を表示

正解:エ

逆ポーランド表記法(後置記法)は「計算する2つの数を先に書き、記号(+−*)を後ろに書く」書き方です。a+b なら ab+ と書きます。読むときは、記号が出たらその直前の2つを計算します。かっこは要りません。

選択肢エの逆ポーランド abcd−*+ を、左から順に処理して元の式に戻してみます(スタックに積んでいくイメージ)。

読む記号やること手元に残る式
a置くa
b置くa, b
c置くa, b, c
d置くa, b, c, d
直前2つ c と d を引くa, b, (c−d)
直前2つ b と (c−d) をかけるa, (b×(c−d))
直前2つ a と (b×(c−d)) を足すa+(b×(c−d))

できあがった式は a+(b*(c−d))。これは選択肢エの左側の計算式とぴったり一致します。よってエが正解です。

なぜ他が違うのか(各組を実際に戻すとズレます):

速解法:逆ポーランドは「記号が出たら直前2つを計算して、その結果をまた1つの数として置く」を左から順にやるだけ。頭からたどって元の式に戻し、左の計算式と一致するものを選べば確実です。

スタック問3 ★スタックが適する計算式の処理

過去問(スタック)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2020-07-26 問8〕
解説を表示

正解:イ

スタックは「あとで入れたものを先に取り出す(後入れ先出し・LIFO)」データ構造です。計算式の処理では「いま計算している途中の値をいったん置いておき、別の計算を先に済ませてから、さっき置いた値を取り出して使う」という場面でスタックが役立ちます。この特徴に合う選択肢を探します。

速解法:選択肢の中で「取り出す順番が入れた順の逆」または「途中でしまって後で戻ってくる」と読めるものがスタック。ア=キュー、エ=リスト、と型を見分ければイが残ります。

木構造問4 ★2分探索木の判定

過去問(木構造)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2020-06-14 問7〕
解説を表示

正解:イ

2分探索木のきまりは「どの節点でも、左側の枝にぶら下がる値はすべて自分より小さく、右側の枝にぶら下がる値はすべて自分より大きい」です。しかも“直接の子だけ”でなく“その下全部”について成り立つ必要があります。各選択肢の根から順にチェックします。

よって正解はイ。

速解法:2分探索木は「左下から右上へ、下から順に読むと(中間順走査)値が小さい順にきれいに並ぶ」性質があります。イを左下から順にたどると 1,2,3,4,5,6,7,8,9 と昇順になり、正しいと確認できます。手早くは、根の左枝に根以上の数・右枝に根以下の数が混ざっている選択肢(ア・ウ・エ)を一発ではじけます。

アルゴリズム問5 ★再帰手続の印字順

過去問(アルゴリズム)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2018-01-28 問7〕
解説を表示

正解:イ

手続 proc(n) がやることは、日本語にすると次の3行だけです。

  1. n が 0 なら何もせず戻る(=ここで打ち止め)
  2. そうでなければ:n を印字 → proc(n-1) を呼ぶ → もう一度 n を印字

ポイントは「1つの n につき、印字が2回ある」こと。しかも2回目の印字は、呼び出した proc(n-1) が全部終わって戻ってきてから行われます。

呼び出しの流れをトレースする

proc(5) を実行すると、次のように内側へ潜っていき、0 で折り返して戻ってきます。

段階実行中の手続行うことここまでの出力
1proc(5)5 を印字 → proc(4) へ5
2proc(4)4 を印字 → proc(3) へ54
3proc(3)3 を印字 → proc(2) へ543
4proc(2)2 を印字 → proc(1) へ5432
5proc(1)1 を印字 → proc(0) へ54321
6proc(0)0 なので何も印字せず戻る(★折り返し点)54321
7proc(1) に戻る2回目の印字:1543211
8proc(2) に戻る2回目の印字:25432112
9proc(3) に戻る2回目の印字:354321123
10proc(4) に戻る2回目の印字:4543211234
11proc(5) に戻る2回目の印字:55432112345

最終的な出力は 5432112345(10桁)。これが選択肢です。

形で覚える

出力は 5 4 3 2 1(下りながらの印字)と 1 2 3 4 5(戻りながらの印字)をそのままつなげた形になります。真ん中が … 2 1 | 1 2 …1が2つ並ぶのが特徴です。n=0 のときは印字せずに戻るので、0 はどこにも出てきません

なぜ他の選択肢が違うのか

速解法

アルゴリズム問6 ★再帰による互除法 f(775,527)

過去問(アルゴリズム)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2019-07-28 問8〕
解説を表示

正解:イ

この関数は「自分自身を呼び出す(再帰)」形で書かれていますが、やっていることはユークリッドの互除法、つまり2つの数の最大公約数を求める手続きです。

ルールはたった2行です。

つまり「割った余りを次の相手にして、余りが0になるまで繰り返す」だけです。f(775, 527) を順に追いかけます。

呼び出しy は 0 かx ÷ y の計算次の呼び出し
1f(775, 527)0でない775 = 527×1 + 248f(527, 248)
2f(527, 248)0でない527 = 248×2 + 31f(248, 31)
3f(248, 31)0でない248 = 31×8 + 0f(31, 0)
4f(31, 0)0!x=31 を返す

4回目でついに y = 0 になったので、そのときの x である 31 が返されます。ここで大事なのは、返ってきた 31 はそのまま一番外側まで戻るという点です。else の行が return f(...) と書かれていて、途中で足したり掛けたりしていないからです。だから f(775, 527) の値も 31 になります。

検算:775 = 31×25、527 = 31×17。確かに両方 31 で割り切れ、25 と 17 にはこれ以上の共通の約数がないので、最大公約数はぴったり 31 です。

なぜ他の選択肢が違うか

速解法if y = 0 then return x という形を見たら、中身を細かく追う前に「これは最大公約数(gcd)だ」と決めうちしてよいです(試験で頻出の超定番パターン)。あとは 775 と 527 の最大公約数を求めるだけ。差をとる手も速く、775 − 527 = 248 なので「248 と 527 の共通約数」を考えればよく、527 = 248×2 + 31、248 = 31×8 でちょうど割り切れる → 答え 31。選択肢のうち 775 と 527 の両方を割り切れる数は 31 しかない、という消去法でも一瞬で決まります。

流れ図問7 ★反復法の収束条件

過去問(流れ図)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2021-06-13 問3〕
解説を表示

正解:エ

この問題は、次の手順をぐるぐる繰り返す手続きです。ポイントは②と④の2つの代入です。

問題文は「十分に繰り返した後、③で表示される y の値に変化がなくなった」と言っています。「もう値が変わらなくなった=落ち着いた状態(収束)」ということです。この落ち着いた状態では、繰り返す前と後で x も y も同じ値になっています。そこで x も y も同じ値だと考えて②の式を見ます。

②は y = f(x)。落ち着いた状態では ④によって xy は等しい(x = y)ので、②の x を y に置きかえられます。すると y = f(y) となります。これが選択肢エです。

数値でイメージしましょう。もし f(x)=(x+2)÷2 のような手続きだと、繰り返すうちに y は 2 に近づいて止まります。そのとき f(2)=(2+2)÷2=2 となり、確かに「y に f を入れても y のまま」= f(y)=y が成り立っています。

なぜ他が違うのか:

速解法:「値が変わらなくなった」=「もう1回入れても同じ」という意味。②の y=f(x)x=y とみなして f(y)=y、と機械的に導けます。

探索問8 ★2分探索の比較回数と log₂n

過去問(探索)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2023-06-11 問6〕
解説を表示

正解:ア

2分探索は、真ん中を1回調べるたびに「探す範囲」がちょうど半分に減っていく探索法です。だから「n個を何回半分にすれば1個になるか」を数えれば、それがおよその比較回数になります。

この「半分に減らせる回数」がまさに log₂n です。たとえば n=8 なら 8→4→2→1 で3回、log₂8=3。n=16 なら 16→8→4→2→1 で4回、log₂16=4。ぴったり合いますね。

データ数 n半分にする回数log₂n
88→4→2→1 で3回3
1616→8→4→2→1 で4回4
102410

ほかの選択肢がなぜダメか整理します。

速解法:「範囲が毎回半分になる=log₂n」はセットで暗記。選択肢に log₂n があれば2分探索・木のたどり方の問題ではそれが本命です。

探索問9 ★ハッシュ法(衝突するキー)

過去問(探索)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2019-12-08 問9〕
解説を表示

正解:エ

ハッシュ法の「衝突」を題材にした問題です。ハッシュ法とは、データを計算でしまう場所を決める方法のこと。今回のルールはとてもシンプルです。

衝突とは、違うキーなのにしまう場所が同じになってしまうことです。つまりこの問題は、「1の位が同じになるペアはどれ?」を探すだけです。

ASCIIコードの求め方

問題文に「アルファベット順に、連続した番号が割り当てられている」とあります。a が 97 であることだけ覚えておけば、あとは順に足していくだけです。

文字aから数えて何番目かASCIIコード1の位=しまう場所
a0977
b1988
c2999
d31000
i81055
l111088
r171144
x231200

※「aから数えて何番目か」は、a=0, b=1, c=2, … と 0 から数えます。たとえば x はアルファベットの24文字目なので、0から数えると23。よって 97+23=120 です。

選択肢を1つずつ確認

選択肢コードしまう場所衝突する?
ア a と i97 と 1057 と 5✘ 別の場所
イ b と r98 と 1148 と 4✘ 別の場所
ウ c と l99 と 1089 と 8✘ 別の場所
エ d と x100 と 1200 と 0同じ場所=衝突

d も x も 0番の場所に入ろうとするので、これが衝突。よって が正解です。

速解法:コードを計算しなくても解ける

実は、97 を足し算する必要すらありません。ここがこの問題のうまいところです。

2つの文字の1の位が同じになるのは、2つのコードの差が10の倍数のときです。そしてコードはアルファベット順に1ずつ増えるので、コードの差=アルファベット順の差。つまり、

「アルファベット順で10個ちょうど離れている(10、20個…離れている)ペアを探す」だけでよいのです。

この解き方なら、指を折って数えるだけで10秒で終わります。

ここで間違えやすいポイント

なお、衝突が起きたときは、次の空いている場所を探す方法や、同じ場所にリストでつなげる方法(チェイン法)で対処します。あわせて押さえておきましょう。

整列問10 ★各整列法の説明の正誤

過去問(整列)
出典:IPA 基本情報技術者試験 科目A(旧・午前)過去問〔2025-06-08 問6〕
解説を表示

正解:エ

この問題は「整列法の名前」と「その説明」がわざと入れ替えられていて、正しく対応している1つを選ぶ形です。1つずつ「名前と中身が合っているか」を確かめます。

選択肢名乗っている名前書かれている中身判定
クイックソート一定間隔の要素で並べ、間隔を詰めていく → 実はシェルソート誤(中身がシェル)
シェルソート隣どうしを比べて逆なら入れ替える → 実はバブルソート誤(中身がバブル)
バブルソート基準値で大きい組・小さい組に振り分ける → 実はクイックソート誤(中身がクイック)
ヒープソート未整列部分を木(順序木)にし、最大値か最小値を取り出して整列済みへ移す正しい

エだけ「ヒープソート」という名前と「木(ヒープ)を作って端の最大・最小を取り出す」という中身がぴったり合っています。だから正解はエです。

ア・イ・ウは、名前は違うのに中身がぐるっとローテーションで入れ替わっているのがポイント。中身自体は正しい整列法の説明なので、つい「合っている」と錯覚しやすいワナです。

速解法:まず各選択肢の「中身」だけ読んで本当の名前を当て(間隔→シェル/隣→バブル/基準値で振り分け→クイック/木→ヒープ)、名乗っている名前と一致する1つを探す。単語対応さえ覚えていれば一瞬で解けます。


【練習リンク】