基本情報技術者過去問題 平成29年春期 午後問13 解説

問題文は他のサイトを別ウインドウで開いてご覧ください。

問題文の表にある数値を引数として、トレースします。

最初のループ

最初のループは3回繰り返します。
ループを開くと以下になります。

相対(B9, 0, 0) ← 相対(B4, 0, 0)
相対(B9, 0, 1) ← 相対(B4, 0, 1)
相対(B9, 0, 2) ← 相対(B4, 0, 2)

これを、左側は該当セルに、右側は入力する数値に置き換えます。

B9 ← 10
C9 ← 36
D9 ← 30

表の値を書き換えます。
A B C D
9 残数量 010 036 030

トレースによりここでは、入力されている発送数量を、梱包作業表(作業に使うために用意された領域)にコピーしていることがわかりました。

荷物番号の初期値を設定します。
packge_no ← 1

荷物を作る

1ループにより1つ荷物を作ります。
残重量(E9)が0になったら終了です。

まず、表示する行を表に作ります。

相対(A15, packge_no, 0) ← packge_no
相対(F15, packge_no, 0) ← F9
相対(G15, packge_no, 0) ← G9

これを、左側は該当セルに、右側は入力する数値に置き換えます。

A16 ← 1
F16 ← 5
G16 ← 1,944

表の値を書き換えます。
A B C D E F G
16 1 5 1,944

重量計算用の変数の初期値を設定します。
work_weight ← 0

内側のループ

商品Xの梱包数をカウントするのですが、まずは0個としてさらに内側のループへ。
B10 ← 0

商品Yの梱包数をカウントするのですが、まずは0個としてさらに内側のループへ。
C10 ← 0

商品Zの梱包数をカウントするのですが、まずは0個とします。
D10 ← 0

E10は自動で計算され更新されます。

表の値を書き換えます。
A B C D E
10 作業数量 0 0 0 0

空欄e

一番大きい箱でも28,680gまでしかはいらないので、それを越えて商品を詰めることはできないのですから、 「E10≦重量区分!E8」とする必要があり、空欄eの選択肢のうち、アとウは消えます。

イとエの選択肢を見ると、いずれも work_weight と E10 を比較していますが、この時点では work_weight も E10 も 0 なので、どちらだったとしても条件に当てはまりません。

よって、1回目は false となり内側の処理を行いません。

ループして商品Zの数が1つ増え、同時にE10の値も更新されます。

D10 ← 1
E10は自動で計算され更新されます。

A B C D E
10 作業数量 0 0 01 01,200

そして、また空欄eの判定を行いますが、今度はE10が更新されたので work_weight と E10 を比較する意味が出来ました。
ループすることによって、常にE10が先行して大きくなっていくのですから、もし選択肢がエだったら、永遠に一番内側のループには入れません。
よって空欄eはイとなります。

変数 k のループ

ループを開くと以下になります。

相対(B15, 1, 0) ← 相対(B10, 0, 0)
相対(B15, 1, 1) ← 相対(B10, 0, 1)
相対(B15, 1, 2) ← 相対(B10, 0, 2)
相対(B15, 1, 3) ← 相対(B10, 0, 3)

これを、左側は該当セルに、右側は入力する数値に置き換えます。
E10には説明文(5)から、B10~D10に格納された数量の合計が計算により入力されます。

B16 ← 0
C16 ← 0
D16 ← 1
E16 ← 1,200

work_weightの値を更新します。
work_weight ← 1,200

表の値を書き換えます。
A B C D E F G
16 1 0 0 1 1,200 5 1,944

以上の処理を30回繰り返して変数kのループを抜けます。

この箱には、28,680gまでしかはいらないので、結果はこうなります。
A B C D E F G
16 1 0 0 23 27,600 5 1,944
work_weight ← 27,600

後述しますが、実はここまでの処理は商品Xと商品Yが0個だったときの、商品Zの最大個数を求めているにすぎません。

変数 j のループ

変数jのループに戻って商品Yを1つ増やします。
変数kに入って30回繰り返し、また変数jに戻って商品Yを1つ増やし、といった具合に、36×30回ループを繰り返し、 商品総重量がより大きくなったときに表を更新します。

後述しますが、実はここまでの処理は商品Yと商品Zの、箱にできるだけ多く詰められる組み合わせを求めているにすぎません。

変数 i のループ

もうわかったと思いますが、今度は商品Xを1づつ増やして全通りの組み合わせを試し、最大となる値を探します。

つまり、このマクロでは10×36×30=10800回ループして全通り試しているのです。
処理が重くてビックリしますが、どうやらそれ以外に方法がないです。

最後のループ

現在の値はこうなっています。
A B C D
9 残数量 10 36 30

3回ループして B C D を更新しますが、1回目だけ空欄 f の選択肢を比較してみます。

ア 相対(B9,0,0) ← 相対(B4,0,0)-相対(B10,0,0)
イ 相対(B9,0,0) ← 相対(B4,0,0)-相対(B15,package_no,0)
ウ 相対(B9,0,0) ← 相対(B9,0,0)-相対(B10,0,0)
エ 相対(B9,0,0) ← 相対(B9,0,0)-相対(B15,package_no,0)

左辺の 相対(B9,0,0) は残数量です。この処理では残数量を更新したいということがわかります。

右辺の (B4,0,0) と (B9,0,0) を比較します。
相対(B4,0,0) は、もともとの発送商品数量のことで変化しません。
2箱目、3箱目となったときに、前の箱で差し引いた値からひき続き減算しなければならないのですから、選択肢アとイは消えます。

相対(B10,0,0) と 相対(B15,package_no,0) を比較します。

相対(B10,0,0) は作業に利用する変数が保存されているセルで、最善個数が保存されているとは限りません。
決定した最善個数は相対(B15,package_no,0) に表示されています。

空欄 f はエです。

package_noを1増やして、ループします。
すべての商品の残数量が 0 になったらマクロを終了します。


ホームに戻るボタン↓