正解:エ
この問題は「10進数を2進数に直す筆算」を、そのまま流れ図にしたものです。まずは手で計算するやり方を思い出しましょう。
10進数を2進数にするときは、2で割った余りを下から順に並べるのでしたね。たとえば13なら:
| わり算 | 商(j div 2) | 余り(j mod 2) |
|---|---|---|
| 13 ÷ 2 | 6 | 1 |
| 6 ÷ 2 | 3 | 0 |
| 3 ÷ 2 | 1 | 1 |
| 1 ÷ 2 | 0 | 1 |
出てきた余りを下から読むと 1101。これが13の2進数です。ここで大事なのは、最初に出た余りが2進数のいちばん下の桁(1の位)だということ。問題文でも「2進数は下位桁から順に NISHIN(1) から格納される」と書かれていて、この筆算の順番とぴったり一致します。
ループは k : 1, 1, 8、つまり k が1から8まで1ずつ増えながら8回まわります。1回のループで「1桁分」を作るわけです。1回のループの中でやるべきことは2つだけ:
NISHIN(k) ← j mod 2j を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 の エ が正解です。
j を割ってしまうので、1の位が失われて答えが半分の値になります。j ← j mod 2 としているのが致命的です。j が余り(0か1)に置き換わってしまうので、2回目以降は j が 0 か 1 のまま動かなくなり、変換がそこで死んでしまいます。しかも配列には商を入れており、役割が完全に逆です。j に余りを入れています。イと同じく j が壊れ、格納する値も間違いです。この形の問題は、選択肢を全部トレースする必要はありません。次の2段階でふるいにかけます。
j に mod を代入している時点でアウト)。合言葉は「取ってから割る」。使う予定の値を、使う前に上書きしてはいけない――これは流れ図の穴埋め問題で何度も出てくる考え方なので、覚えておくと得です。
正解:エ
逆ポーランド表記法(後置記法)は「計算する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))。これは選択肢エの左側の計算式とぴったり一致します。よってエが正解です。
なぜ他が違うのか(各組を実際に戻すとズレます):
abc*+d− を戻すと、c*→(b×c)、+→a+(b×c)、d−→(a+(b×c))−d となり、左の式 ((a+b)*c)−d と食い違います。ab+c*d− を戻すと ((a+b)*c)−d になり、左の式 (a+(b*c))−d と食い違います(アとイは式と表記が入れ替わっています)。abc*d−+ を戻すと a+((b*c)−d) となり、左の式 (a+b)*(c−d) と食い違います。速解法:逆ポーランドは「記号が出たら直前2つを計算して、その結果をまた1つの数として置く」を左から順にやるだけ。頭からたどって元の式に戻し、左の計算式と一致するものを選べば確実です。
正解:イ
スタックは「あとで入れたものを先に取り出す(後入れ先出し・LIFO)」データ構造です。計算式の処理では「いま計算している途中の値をいったん置いておき、別の計算を先に済ませてから、さっき置いた値を取り出して使う」という場面でスタックが役立ちます。この特徴に合う選択肢を探します。
速解法:選択肢の中で「取り出す順番が入れた順の逆」または「途中でしまって後で戻ってくる」と読めるものがスタック。ア=キュー、エ=リスト、と型を見分ければイが残ります。
正解:イ
2分探索木のきまりは「どの節点でも、左側の枝にぶら下がる値はすべて自分より小さく、右側の枝にぶら下がる値はすべて自分より大きい」です。しかも“直接の子だけ”でなく“その下全部”について成り立つ必要があります。各選択肢の根から順にチェックします。
よって正解はイ。
速解法:2分探索木は「左下から右上へ、下から順に読むと(中間順走査)値が小さい順にきれいに並ぶ」性質があります。イを左下から順にたどると 1,2,3,4,5,6,7,8,9 と昇順になり、正しいと確認できます。手早くは、根の左枝に根以上の数・右枝に根以下の数が混ざっている選択肢(ア・ウ・エ)を一発ではじけます。
正解:イ
手続 proc(n) がやることは、日本語にすると次の3行だけです。
n が 0 なら何もせず戻る(=ここで打ち止め)ポイントは「1つの n につき、印字が2回ある」こと。しかも2回目の印字は、呼び出した proc(n-1) が全部終わって戻ってきてから行われます。
proc(5) を実行すると、次のように内側へ潜っていき、0 で折り返して戻ってきます。
| 段階 | 実行中の手続 | 行うこと | ここまでの出力 |
|---|---|---|---|
| 1 | proc(5) | 5 を印字 → proc(4) へ | 5 |
| 2 | proc(4) | 4 を印字 → proc(3) へ | 54 |
| 3 | proc(3) | 3 を印字 → proc(2) へ | 543 |
| 4 | proc(2) | 2 を印字 → proc(1) へ | 5432 |
| 5 | proc(1) | 1 を印字 → proc(0) へ | 54321 |
| 6 | proc(0) | 0 なので何も印字せず戻る(★折り返し点) | 54321 |
| 7 | proc(1) に戻る | 2回目の印字:1 | 543211 |
| 8 | proc(2) に戻る | 2回目の印字:2 | 5432112 |
| 9 | proc(3) に戻る | 2回目の印字:3 | 54321123 |
| 10 | proc(4) に戻る | 2回目の印字:4 | 543211234 |
| 11 | proc(5) に戻る | 2回目の印字:5 | 5432112345 |
最終的な出力は 5432112345(10桁)。これが選択肢イです。
出力は 5 4 3 2 1(下りながらの印字)と 1 2 3 4 5(戻りながらの印字)をそのままつなげた形になります。真ん中が … 2 1 | 1 2 … と1が2つ並ぶのが特徴です。n=0 のときは印字せずに戻るので、0 はどこにも出てきません。
proc(1) も他と同じく印字を2回するので、1 は2回出ます。proc(0) は「0 ならば戻る」で、印字する行に到達せずに帰ってしまうので、0 は絶対に出力されません。「n を印字してから 0 かどうか判定する」と読み違えるとこうなります。proc(1) をやってみると「1を印字 → proc(0)は何もしない → 1を印字」で 11。次に proc(2) は「2 → (proc(1)=11) → 2」で 2112。この時点で「真ん中は 11 で、0 は出ない」と分かるので、0 を含むウ・エは即除外、1が1つのアも除外。残るイが正解です。再帰は n=1 や n=2 の小さいケースで形を掴むのが最速です。5 × 2 = 10 桁。選択肢の桁数を数えるだけで、9桁のア・11桁のウ・12桁のエが消え、10桁のイだけが残ります。これが一番速い解き方です。
正解:イ
この関数は「自分自身を呼び出す(再帰)」形で書かれていますが、やっていることはユークリッドの互除法、つまり2つの数の最大公約数を求める手続きです。
ルールはたった2行です。
y が 0 になったら、そのときの x を答えとして返す(これが再帰の終わり=ベースケース)。(x, y) を (y, x を y で割った余り) に置きかえて、もう一度同じ関数を呼ぶ。つまり「割った余りを次の相手にして、余りが0になるまで繰り返す」だけです。f(775, 527) を順に追いかけます。
| 回 | 呼び出し | y は 0 か | x ÷ y の計算 | 次の呼び出し |
|---|---|---|---|---|
| 1 | f(775, 527) | 0でない | 775 = 527×1 + 248 | f(527, 248) |
| 2 | f(527, 248) | 0でない | 527 = 248×2 + 31 | f(248, 31) |
| 3 | f(248, 31) | 0でない | 248 = 31×8 + 0 | f(31, 0) |
| 4 | f(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 です。
なぜ他の選択肢が違うか
y ではなく x です。y の値そのもの。何も計算していない状態です。速解法: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 しかない、という消去法でも一瞬で決まります。
正解:エ
この問題は、次の手順をぐるぐる繰り返す手続きです。ポイントは②と④の2つの代入です。
y ← f(x)(x を関数に入れた結果を y にする)x ← y(その y を次の x にする)問題文は「十分に繰り返した後、③で表示される y の値に変化がなくなった」と言っています。「もう値が変わらなくなった=落ち着いた状態(収束)」ということです。この落ち着いた状態では、繰り返す前と後で x も y も同じ値になっています。そこで x も y も同じ値だと考えて②の式を見ます。
②は y = f(x)。落ち着いた状態では ④によって x と y は等しい(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 が成り立っています。
なぜ他が違うのか:
f(a)=y の a は最初の1回目に使う初期値(①)だけの値です。何度も繰り返して落ち着いた後の関係とは無関係なので誤り。f(y)=0 は「答えが必ず0になる」という決めつけで、この手続きにそんな条件はありません。f(y)=a も、落ち着いた後の値が初期値 a に戻る理由がなく誤り。速解法:「値が変わらなくなった」=「もう1回入れても同じ」という意味。②の y=f(x) で x=y とみなして f(y)=y、と機械的に導けます。
正解:ア
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 |
|---|---|---|
| 8 | 8→4→2→1 で3回 | 3 |
| 16 | 16→8→4→2→1 で4回 | 4 |
| 1024 | — | 10 |
ほかの選択肢がなぜダメか整理します。
log₂n です。速解法:「範囲が毎回半分になる=log₂n」はセットで暗記。選択肢に log₂n があれば2分探索・木のたどり方の問題ではそれが本命です。
正解:エ
ハッシュ法の「衝突」を題材にした問題です。ハッシュ法とは、データを計算でしまう場所を決める方法のこと。今回のルールはとてもシンプルです。
衝突とは、違うキーなのにしまう場所が同じになってしまうことです。つまりこの問題は、「1の位が同じになるペアはどれ?」を探すだけです。
問題文に「アルファベット順に、連続した番号が割り当てられている」とあります。a が 97 であることだけ覚えておけば、あとは順に足していくだけです。
| 文字 | aから数えて何番目か | ASCIIコード | 1の位=しまう場所 |
|---|---|---|---|
| a | 0 | 97 | 7 |
| b | 1 | 98 | 8 |
| c | 2 | 99 | 9 |
| d | 3 | 100 | 0 |
| i | 8 | 105 | 5 |
| l | 11 | 108 | 8 |
| r | 17 | 114 | 4 |
| x | 23 | 120 | 0 |
※「aから数えて何番目か」は、a=0, b=1, c=2, … と 0 から数えます。たとえば x はアルファベットの24文字目なので、0から数えると23。よって 97+23=120 です。
| 選択肢 | コード | しまう場所 | 衝突する? |
|---|---|---|---|
| ア a と i | 97 と 105 | 7 と 5 | ✘ 別の場所 |
| イ b と r | 98 と 114 | 8 と 4 | ✘ 別の場所 |
| ウ c と l | 99 と 108 | 9 と 8 | ✘ 別の場所 |
| エ d と x | 100 と 120 | 0 と 0 | ✔ 同じ場所=衝突 |
d も x も 0番の場所に入ろうとするので、これが衝突。よって エ が正解です。
実は、97 を足し算する必要すらありません。ここがこの問題のうまいところです。
2つの文字の1の位が同じになるのは、2つのコードの差が10の倍数のときです。そしてコードはアルファベット順に1ずつ増えるので、コードの差=アルファベット順の差。つまり、
「アルファベット順で10個ちょうど離れている(10、20個…離れている)ペアを探す」だけでよいのです。
この解き方なら、指を折って数えるだけで10秒で終わります。
なお、衝突が起きたときは、次の空いている場所を探す方法や、同じ場所にリストでつなげる方法(チェイン法)で対処します。あわせて押さえておきましょう。
正解:エ
この問題は「整列法の名前」と「その説明」がわざと入れ替えられていて、正しく対応している1つを選ぶ形です。1つずつ「名前と中身が合っているか」を確かめます。
| 選択肢 | 名乗っている名前 | 書かれている中身 | 判定 |
|---|---|---|---|
| ア | クイックソート | 一定間隔の要素で並べ、間隔を詰めていく → 実はシェルソート | 誤(中身がシェル) |
| イ | シェルソート | 隣どうしを比べて逆なら入れ替える → 実はバブルソート | 誤(中身がバブル) |
| ウ | バブルソート | 基準値で大きい組・小さい組に振り分ける → 実はクイックソート | 誤(中身がクイック) |
| エ | ヒープソート | 未整列部分を木(順序木)にし、最大値か最小値を取り出して整列済みへ移す | 正しい |
エだけ「ヒープソート」という名前と「木(ヒープ)を作って端の最大・最小を取り出す」という中身がぴったり合っています。だから正解はエです。
ア・イ・ウは、名前は違うのに中身がぐるっとローテーションで入れ替わっているのがポイント。中身自体は正しい整列法の説明なので、つい「合っている」と錯覚しやすいワナです。
速解法:まず各選択肢の「中身」だけ読んで本当の名前を当て(間隔→シェル/隣→バブル/基準値で振り分け→クイック/木→ヒープ)、名乗っている名前と一致する1つを探す。単語対応さえ覚えていれば一瞬で解けます。