令和4年度 春期 応用情報技術者試験 午後 問3 深さ優先探索による数独解法プログラムの盤面走査とデータ構造改善

学習ガイド

9×9のマス目に数字を当てはめる数独パズルを題材に、バックトラック法による探索処理を実装する問題です。論点は、1次元配列上で縦横と枠の重複を調べる添字計算と、枝刈りのために候補を管理するデータ構造Zの扱いです。まずは探索手順と図3の配列構造を確認し、行や列の先頭インデックスを求める数式を導きます。後半の改善処理では、数字を試す際と手戻り発生時に状態をどう保持・復元するかを読み取りましょう。

この記事で押さえる論点

  • 再帰呼出しを用いた深さ優先探索によるバックトラック処理の流れを説明できる
  • 1次元配列で表現された9×9盤面の行・列・枠の先頭位置を添字計算で特定できる理由を述べられる
  • 候補数字を管理するデータ構造Zを導入することで重複チェックを効率化する仕組みを説明できる
  • 探索の試行とバックトラックに伴うデータ構造Zの退避と復元の必要性を説明できる

問題本文

問3 パズルの解答を求めるプログラムに関する次の記述を読んで,設問1〜3に答えよ。

太線で3×3の枠に区切られた9×9のマスから成る正方形の盤面に,1〜9の数字を入れるパズルの解答を求めるプログラムを考える。このパズルは,図1に示すように幾つかのマスに数字が入れられている状態から,数字の入っていない各マスに,1〜9のうちのどれか一つの数字を入れていく。このとき,盤面の横1行,縦1列,及び太線で囲まれた3×3の枠内の全てにおいて,1〜9の数字が一つずつ入ることが,このパズルのルールである。パズルの問題例を図1に,図1の解答を図2に示す。

図1 問題例
図の説明テキスト

図1 問題例

2 1 9 7
4 2 3
5 8 2 9
9 6 7 2
6 3 5 4
7 4 9 1
7 6 9 3
9 6 4
4 1 6
図2 図1の解答
図の説明テキスト

図2 図1の解答

2 8 1 4 9 3 7 6 5
9 4 6 2 5 7 3 8 1
5 7 3 1 6 8 4 2 9
4 9 5 6 7 1 2 3 8
6 1 8 3 2 5 9 7 4
3 2 7 8 4 9 5 1 6
7 6 2 9 8 4 1 5 3
1 5 9 7 3 6 8 4 2
8 3 4 5 1 2 6 9 7

このパズルを解くための方針を次に示す。

方針
図の説明テキスト

方針:数字が入っていない空白のマスに、1〜9の数字を入れて、パズルのルールにのっとって全部のマスを埋めることができる解答を探索する。

この方針に沿ってパズルを解く手順を考える。

〔パズルを解く手順〕

(1) 盤面の左上端から探索を開始する。マスは左端から順に右方向に探索し,右端に達したら一行下がり,左端から順に探索する。
(2) 空白のマスを見つける。
(3) (2)で見つけた空白のマスに,1〜9の数字を順番に入れる。
(4) 数字を入れたときに,その状態がパズルのルールにのっとっているかどうかをチェックする。

(4-1) ルールにのっとっている場合は,(2)に進んで次の空白のマスを見つける。

(4-2) ルールにのっとっていない場合は,(3)に戻って次の数字を入れる。このとき,入れる数字がない場合には,マスを空白に戻して一つ前に数字を入れたマスに戻り,(3)から再開する。

(5) 最後のマスまで数字が入り,空白のマスがなくなったら,それが解答となる。

〔盤面の表現〕

この手順をプログラムに実装するために,9×9の盤面を次のデータ構造で表現することにした。

  • 9×9の盤面を81個の要素をもつ1次元配列 board で表現する。添字は0から始まる。各要素にはマスに入れられた数字が格納され,空白の場合は0を格納する。

配列 board による盤面の表現を図3に示す。ここで括弧内の数字は配列 board の添字を表す。

図3 配列 board による盤面の表現
図の説明テキスト

図3 配列 board による盤面の表現

[0] [1] [2] [3] [4] [5] [6] [7] [8]
[9] [10] [11] [12] [13] [14] [15] [16] [17]
[18] [19] [20] [21] [22] [23] [24] [25] [26]
[27] [28] [29] [30] [31] [32] [33] [34] [35]
... ... ... ... ... ... ... ... ...
[72] [73] [74] [75] [76] [77] [78] [79] [80]

〔ルールのチェック方法〕

パズルのルールにのっとっているかどうかのチェックでは,数字を入れたマスが含まれる横1行の左端のマス,縦1列の上端のマス,3×3の枠内の左上端のマスを特定し,行,列,枠内のマスに既に格納されている数字と,入れた数字がそれぞれ重複していないことを確認する。このチェックを“重複チェック”という。

〔解法のプログラム〕

プログラムで使用する配列,関数,変数及び定数の一部を表1に示す。なお,表1の配列及び変数は大域変数とする。

表1 プログラムで使用する配列,関数,変数及び定数の一部
図の説明テキスト

表1 プログラムで使用する配列,関数,変数及び定数の一部

名称 種類 内容
board[ ] 配列 盤面の情報を格納する配列。初期化時には問題に合わせて要素に数字が設定される。
solve(x) 関数 パズルを解くための手順を実行する関数。盤面を表すboard[ ]の添字xを引数とする。
row_ok(n, x) 関数 横1行の重複チェックを行う関数。チェック対象の数字n,チェック対象のマスを示す添字xを引数とする。数字の重複がない場合はtrue,重複がある場合はfalseを返す。
column_ok(n, x) 関数 縦1列の重複チェックを行う関数。チェック対象の数字n,チェック対象のマスを示す添字xを引数とする。数字の重複がない場合はtrue,重複がある場合はfalseを返す。
frame_ok(n, x) 関数 3×3の枠内の重複チェックを行う関数。チェック対象の数字n,チェック対象のマスを示す添字xを引数とする。数字の重複がない場合はtrue,重複がある場合はfalseを返す。
check_ok(n, x) 関数 row_ok, column_ok, frame_okを呼び出し,全ての重複チェックを実行する関数。チェック対象の数字n,チェック対象のマスを示す添字xを引数とする。全てのチェックで数字の重複がない場合はtrue,一つ以上のチェックで数字の重複がある場合はfalseを返す。
div(n, m) 関数 整数nを整数mで割った商を求める関数。
mod(n, m) 関数 整数nを整数mで割った剰余を求める関数。
print_board( ) 関数 board[ ]の内容を9×9の形に出力する関数。
row_top 変数 数字を入れようとするマスが含まれる横1行の左端のマスを示す添字を格納する変数。
column_top 変数 数字を入れようとするマスが含まれる縦1列の上端のマスを示す添字を格納する変数。
frame_top 変数 数字を入れようとするマスが含まれる3×3の枠内の左上端のマスを示す添字を格納する変数。
MAX_BOARD 定数 盤面に含まれるマスの数を表す定数で81。

解法のプログラムのメインプログラムを図4に,関数solveのプログラムを図5に,重複チェックを行うプログラムの一部を図6に示す。

図4 メインプログラム
図の説明テキスト

図4 メインプログラム

function main()
  board[]を初期化する //問題を盤面に設定する
  solve(0) //盤面の左上端のマスを示す添字を引数として関数solveを呼び出す
endfunction
図5 関数 solve のプログラム
図の説明テキスト

図5 関数 solve のプログラム

function solve(x)
  if (x が MAX_BOARD-1 より大きい)
    print_board()          // 解答を出力する
    exit()                 // メインプログラムの処理を終了する
  else
    if ( <span id="q3_blank_a" class="blank-label">ア</span> )            // 対象のマスが空白でない場合
      solve ( <span id="q3_blank_i" class="blank-label">イ</span> )       // 次の探索
    else
      for (n を 1 から 9 まで 1 ずつ増やす) // 1〜9 の数字を順にマスに入れる
        if ( <span id="q3_blank_u" class="blank-label">ウ</span> )
          board[x] ← n
          solve ( <span id="q3_blank_i" class="blank-label">イ</span> )   // 次の探索
          board[x] ← <span id="q3_blank_e" class="blank-label">エ</span>   // 再帰から戻った場合のマスの初期化
        endif
      endfor
    endif
  endif
endfunction
図6 重複チェックを行うプログラムの一部
図の説明テキスト

図6 重複チェックを行うプログラムの一部

function row_ok(n, x)         // 横 1 行の重複チェック
  row_top ← <span id="q3_blank_o" class="blank-label">オ</span>              // 行の左端のマスを示す添字を求める
  for (i を 0 から 8 まで 1 ずつ増やす)
    if ( <span id="q3_blank_ka" class="blank-label">カ</span> )
      return false
    endif
  endfor
  return true
endfunction

function column_ok(n, x)      // 縦 1 列の重複チェック
  column_top ← <span id="q3_blank_ki" class="blank-label">キ</span>           // 列の上端のマスを示す添字を求める
  for (i を 0 から 8 まで 1 ずつ増やす)
    if ( <span id="q3_blank_ku" class="blank-label">ク</span> )
      return false
    endif
  endfor
  return true
endfunction

function frame_ok(n, x)       // 3×3 の枠内の重複チェック
  frame_top ← x - <span id="q3_blank_ke" class="blank-label">ケ</span> - mod(x, 3) // 枠内の左上端のマスを示す添字を求める
  for (i を 0 から 2 まで 1 ずつ増やす)
    for (j を 0 から 2 まで 1 ずつ増やす)
      if (board[frame_top + 9 * i + j]が n と等しい)
        return false
      endif
    endfor
  endfor
  return true
endfunction

〔プログラムの改善〕

解法のプログラムは深さ優先探索であり,探索の範囲が広くなるほど,再帰呼び出しの回数が指数関数的に増加し,重複チェックの実行回数も増加する。

そこで,重複チェックの実行回数を少なくするために,各マスに入れることができる数字を保持するためのデータ構造Zを考える。データ構造Zは盤面のマスの数×9の要素をもち,添字xは0から,添字nは1から始まる2次元配列とする。Z[x][n]は,ゲームのルールにのっとってboard[x]に数字nを入れることができる場合は要素に1を,できない場合は要素に0を格納する。データ構造Zの初期化処理と更新処理を表2のように定義した。

なお,データ構造Zは大域変数として導入する。

表2 データ構造Zの初期化処理と更新処理
図の説明テキスト

表2 データ構造Zの初期化処理と更新処理

処理の名称 処理の内容
初期化処理 初期化時の盤面に対し,個々の空白のマスについて 1〜9 の数字を入れた場合の重複チェックを行う。
重複チェックの結果によって,初期化時の盤面の状態で個々の空白のマスに入れることができない数字は,データ構造Zの該当する数字の要素に 0 を設定する。それ以外の要素には 1 を設定する。
更新処理 空白のマスに数字を入れたとき,そのマスが含まれる横1行,縦1列,3×3の枠内の全てのマスを対象に,データ構造Zの該当する数字の要素を 0 に更新する。

〔パズルを解く手順〕の(1)の前にデータ構造Zの初期化処理を追加し,〔パズルを解く手順〕の(2)〜(5)を次の(2)〜(4)のように変更した。

(2) 空白のマスを見つける。

(3) データ構造Zを参照し,(2)で見つけた空白のマスに入れることができる数字のリストを取得し,リストの数字を順番に入れる。

(3-1) 入れる数字がある場合,①処理 Aを行った後,マスに数字を入れる。その後,データ構造Zの更新処理を行い,(2)に進んで次の空白のマスを見つける。

(3-2) 入れる数字がない場合,マスを空白に戻し,②処理 Bを行った後,一つ前に数字を入れたマスに戻り,戻ったマスで取得したリストの次の数字から再開する。

(4) 最後のマスまで数字が入り,空白のマスがなくなったら,それが解答となる。

設問と解答・解説

設問1

図5中のア〜エに入れる適切な字句を答えよ。

(1)配点 1点

模範解答

board[x]が0でない

採点基準

正確性(内容)1点
  • 1点: 「board[x]が0でない」と正しく記述されている。
  • 0点: 解答が不完全、または誤った表現が含まれている。
  • 0点: 無回答、または全く異なる内容が記述されている。

解説

設問の解説

関数 solve(x) における <span id="q3_blank_a" class="blank-label">ア</span> は、直前のコメントに「対象のマスが空白でない場合」と記載されている if 文の条件式です。
〔盤面の表現〕において、盤面は1次元配列 board で表現され、「空白の場合は 00 を格納する」と定義されています。
したがって、対象のマス board[x] が空白でないことを判定する条件式は、board[x]が0でない となります。

高得点のポイント

  • 問題文中の配列名 board と添字 x を正しく用いる。
  • 空白が 00 で表現されるという仕様に基づき、適切に比較式を表現する。
(2)配点 1点

模範解答

x+1

採点基準

正確性(内容)1点
  • 1点: 「x+1」と正しく記述されている。
  • 0点: 解答が不完全、または誤った表現が含まれている。
  • 0点: 無回答、または全く異なる内容が記述されている。

解説

設問の解説

対象のマスが空白でない場合、またはマスに数字を入れた後、次の探索に進むために再帰的に関数 solve を呼び出します(<span id="q3_blank_i" class="blank-label">イ</span>)。
〔パズルを解く手順〕の(1)には「マスは左端から順に右方向に探索し,右端に達したら一行下がり,左端から順に探索する」とあります。
また、図3「配列 board による盤面の表現」から、添字は 0,1,2,…0, 1, 2, \dots と連番で振られており、右隣のマスや次の行の左端のマスに進むことは、添字の値を 11 増やすことに相当します。
したがって、現在探索中のマスの添字が x のとき、次に探索するマスの添字は x+1 となります。

高得点のポイント

  • 探索順が配列の添字の順序と完全に一致していることを理解する。
  • 添字を 11 つ進める式 x+1 を正しく記述する。
(3)配点 1点

模範解答

check_ok(n, x)がtrueと等しい

採点基準

正確性(内容)1点
  • 1点: 「check_ok(n, x)がtrueと等しい」と正しく記述されている。
  • 0点: 解答が不完全、または誤った表現が含まれている。
  • 0点: 無回答、または全く異なる内容が記述されている。

解説

設問の解説

<span id="q3_blank_u" class="blank-label">ウ</span> の if 文が成立したときに board[x] ← n として数字をマスに入れています。
〔パズルを解く手順〕の(4)には「数字を入れたときに,その状態がパズルのルールにのっとっているかどうかをチェックする」とあります。
ルールのチェックは、表1の「全ての重複チェックを実行する関数」で行います。この関数は check_ok(n, x) であり、「全てのチェックで数字の重複がない場合は true」を返します。
したがって、ルールにのっとっている(重複がない)ことを判定する式は check_ok(n, x)がtrueと等しい となります。

高得点のポイント

  • 表1に定義された関数 check_ok を正しく選択する。
  • 関数が返す true / false を用いて、正しく条件式を記述する。
(4)配点 1点

模範解答

0

採点基準

正確性(内容)1点
  • 1点: 「0」と正しく記述されている。
  • 0点: 解答が不完全、または誤った表現が含まれている。
  • 0点: 無回答、または全く異なる内容が記述されている。

解説

設問の解説

<span id="q3_blank_e" class="blank-label">エ</span> は、コメントに「再帰から戻った場合のマスの初期化」とあります。
〔パズルを解く手順〕の(4-2)には「入れる数字がない場合には,マスを空白に戻して一つ前に数字を入れたマスに戻り」と記載されています。
〔盤面の表現〕において「空白の場合は 00 を格納する」と定義されているため、マスを空白に戻すには board[x] に 0 を代入する必要があります。

高得点のポイント

  • 探索が行き詰まってバックトラックする際の処理(マスを空白に戻す)を理解する。
  • 空白を表す値が 00 であることに基づき記述する。

設問2

図6中のオ〜ケに入れる適切な字句を答えよ。

(1)配点 2点

模範解答

div(x, 9)*9

採点基準

正確性(内容)2点
  • 2点: 「div(x, 9)*9」と正しく記述されている。
  • 1点: 計算の意図は合っているが、使用する関数や記述に軽微な誤りがある。
  • 0点: 無回答、または全く異なる内容が記述されている。

解説

設問の解説

関数 row_ok(n, x) の <span id="q3_blank_o" class="blank-label">オ</span> は、行の左端のマスを示す添字 row_top を求める処理です。
図3の盤面表現において、各行の左端のマスの添字は 0,9,18,27,…0, 9, 18, 27, \dots と、99 の倍数になります。
あるマス x が含まれる行の左端の添字を求めるには、x を 99 で割った商(何行目か)に 99 を掛けます。
表1に「整数 nn を整数 mm で割った商を求める関数 div(n, m)」が用意されているため、これを適用して div(x, 9)*9 となります。

高得点のポイント

  • 行の先頭の添字が 99 の倍数であることを図3から読み取る。
  • 問題文で指定された関数 div を用いて正しく計算式を表現する。
(2)配点 2点

模範解答

board[row_top+i]がnと等しい

採点基準

正確性(内容)2点
  • 2点: 「board[row_top+i]がnと等しい」と正しく記述されている。
  • 1点: 条件の意図は合っているが、配列の添字や比較表現に軽微な誤りがある。
  • 0点: 無回答、または全く異なる内容が記述されている。

解説

設問の解説

<span id="q3_blank_ka" class="blank-label">カ</span> は、関数 row_ok における重複チェックの条件式です。
行の左端の添字 row_top から始まり、右方向に 99 個のマスを調べます。
ループ変数 i が 00 から 88 まで増えるため、各マスの値は board[row_top+i] と表せます。
これが新たに入れようとする数字 n と等しい場合、重複が発生しているため return false となります。
よって、条件式は board[row_top+i]がnと等しい となります。

高得点のポイント

  • チェック対象のマスの添字が row_top + i であることを理解する。
  • 配列 board の該当要素と n が等しいかどうかの比較を正しく表現する。
(3)配点 2点

模範解答

mod(x, 9)

採点基準

正確性(内容)2点
  • 2点: 「mod(x, 9)」と正しく記述されている。
  • 1点: 計算の意図は合っているが、使用する関数や記述に軽微な誤りがある。
  • 0点: 無回答、または全く異なる内容が記述されている。

解説

設問の解説

関数 column_ok(n, x) の <span id="q3_blank_ki" class="blank-label">キ</span> は、列の上端のマスを示す添字 column_top を求める処理です。
図3の盤面表現において、各列の上端のマスの添字は 0,1,2,3,4,5,6,7,80, 1, 2, 3, 4, 5, 6, 7, 8 です。
あるマス x が含まれる列の上端の添字は、x を 99 で割った余りと一致します。
表1に「整数 nn を整数 mm で割った剰余を求める関数 mod(n, m)」が用意されているため、これを適用して mod(x, 9) となります。

高得点のポイント

  • 列の上端の添字が、各添字を 99 で割った余りに等しいことを図3から読み取る。
  • 問題文で指定された関数 mod を用いて正しく計算式を表現する。
(4)配点 2点

模範解答

board[column_top+9*i]がnと等しい

採点基準

正確性(内容)2点
  • 2点: 「board[column_top+9*i]がnと等しい」と正しく記述されている。
  • 1点: 条件の意図は合っているが、配列の添字や比較表現に軽微な誤りがある。
  • 0点: 無回答、または全く異なる内容が記述されている。

解説

設問の解説

<span id="q3_blank_ku" class="blank-label">ク</span> は、関数 column_ok における重複チェックの条件式です。
列の上端の添字 column_top から始まり、下方向に 99 個のマスを調べます。
同じ列の 11 つ下のマスに進むには、添字に 99 を足します。したがって、ループ変数 i が 00 から 88 まで増えるとき、各マスの添字は column_top + 9 * i となります。
対象マスの値 board[column_top+9*i] が新たに入れようとする数字 n と等しい場合、重複していることになります。
よって、条件式は board[column_top+9*i]がnと等しい となります。

高得点のポイント

  • 縦方向のマス移動が添字の +9+9 に相当することを理解する。
  • チェック対象の添字が column_top + 9*i であることを見抜き、正しく比較式を表現する。
(5)配点 2点

模範解答

mod(div(x, 9)*9, 27)

採点基準

正確性(内容)2点
  • 2点: 「mod(div(x, 9)*9, 27)」と正しく記述されている。
  • 1点: 計算の意図は合っているが、使用する関数や記述に軽微な誤りがある。
  • 0点: 無回答、または全く異なる内容が記述されている。

解説

設問の解説

関数 frame_ok(n, x) の <span id="q3_blank_ke" class="blank-label">ケ</span> は、3×33\times3 の枠内の左上端のマスを示す添字 frame_top を求める計算式の一部です。
プログラム中の式は frame_top ← x - ケ - mod(x, 3) となっています。
枠内の左上端のマスを求めるには、x に含まれる「枠内での行方向のオフセット」と「枠内での列方向のオフセット」を引く必要があります。
列方向のオフセットは mod(x, 3) で求まります(式中の - mod(x, 3))。
行方向のオフセットは、現在いる行が 3×33\times3 ブロックの中で上から何段目(0,1,20, 1, 2 段目)にあるかによって決まります。
行の先頭の添字は div(x, 9)*9(オの答え)です。この行番号 div(x, 9) が 33 行ごとにグループ化されているため、ブロック内での相対行番号は div(x, 9) を 33 で割った余り mod(div(x, 9), 3) となります。
実際の添字の差分(オフセット)はこれを 99 倍した mod(div(x, 9), 3) * 9 です。
これを変形すると mod(div(x, 9)*9, 27) となります。
したがって、引くべき行方向のオフセット <span id="q3_blank_ke" class="blank-label">ケ</span> には mod(div(x, 9)*9, 27) が入ります。

高得点のポイント

  • 3×33\times3 枠の左上端の計算において、行方向の差分と列方向の差分を分けて考える。
  • 剰余と商の性質(div と mod)を利用して、行方向のオフセットを正しく数式化する。

設問2のケは,正答率が低かった。添字x,3×3の枠内の先頭の数字,mod(x, 3)の組合せを列挙することで,ケが取るべき値を求めることができる。剰余や商の性質を理解し,着実に計算することで正答を導き出してほしい。

設問3

〔プログラムの改善〕について,下線①の処理A及び下線②の処理Bの内容を,“データ構造Z”という字句を含めて,それぞれ20字以内で述べよ。

(1)配点 3点

下線①の処理Aの内容を,“データ構造Z”という字句を含めて,20字以内で述べよ。

模範解答

データ構造Zを退避する

採点基準

知識・理解度(内容)2点
  • 2点: 再帰呼び出しで大域変数が変更される前に、元の状態を保存(退避)する必要があることが明確に示されている。
  • 1点: 状態を保存(退避)することに触れているが、説明が不十分である。
  • 0点: 上記の内容が含まれていない。
論理性(構造)1点
  • 1点: 文意が明確であり、日本語として自然な構成になっている。
  • 0点: 文意が不明確である、または論理的なつながりが破綻している。

解説

設問の解説

〔プログラムの改善〕において、データ構造 ZZ は大域変数として導入され、各マスに入れることができる数字を管理します。
(3-1) でマスに数字を入れた後、ZZ の該当する数字の要素を 00 に更新して再帰呼び出し(次の探索)を行います。
しかし、探索が失敗して(3-2)で戻ってきた場合、マスを空白に戻すとともに、ZZ の内容も「数字を入れる前の状態」に戻さなければなりません。
ZZ の更新処理の逆を行うのは計算コストがかかるため、下線①の処理Aにおいて、あらかじめ変更前の状態の データ構造 ZZ を退避する ことで、戻ってきた際に復元できるようにします。

高得点のポイント

  • 再帰呼び出し(深さ優先探索)において、大域変数を変更する前に元の状態を保存する必要性を理解する。
  • 「データ構造 ZZ」という指定字句を含め、退避や保存を行う旨を文字数制限(2020 字以内)で端的に記述する。
(2)配点 3点

下線②の処理Bの内容を,“データ構造Z”という字句を含めて,20字以内で述べよ。

模範解答

退避したデータ構造Zを取り出す

採点基準

知識・理解度(内容)2点
  • 2点: バックトラック時に、処理Aで退避しておいた状態を復元(取り出す)する必要があることが明確に示されている。
  • 1点: 状態を復元(取り出す)することに触れているが、説明が不十分である。
  • 0点: 上記の内容が含まれていない。
論理性(構造)1点
  • 1点: 文意が明確であり、日本語として自然な構成になっている。
  • 0点: 文意が不明確である、または論理的なつながりが破綻している。

解説

設問の解説

(3-2) は探索が失敗してバックトラック(一つ前の状態に戻る)する際の処理です。
(3-1)の処理Aで退避しておいたデータ構造 ZZ を使って、大域変数 ZZ を探索前の状態に復元する必要があります。
したがって、下線②の処理Bでは、マスを空白に戻すのに合わせて、退避したデータ構造 ZZ を取り出す(または復元する)処理を行います。

高得点のポイント

  • バックトラック時に、退避しておいた大域変数の状態を元に戻す必要があることを理解する。
  • 「データ構造 ZZ」という指定字句を含め、退避したデータの復元を行う旨を文字数制限(2020 字以内)で端的に記述する。

設問3は,正答率が低かった。下線②の“処理B”では,“マスを空白に戻す”のに合わせて,データ構造Zも数字を入れる前の状態に戻す必要がある。これを,Zの内容を実際に更新して行う代わりに,大域変数として導入したZを,下線①の“処理A”で一時退避しておき,“処理B”ではそれを取り出すことによって実現できることを理解してほしい。

Spineチーム