平成28年度秋期午後のC言語問題である問9の私の解き方・考え方について解説していきます。
問題
IPAの公式サイトで公開されています。このページでは問9についての解説を行います。
https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2016h28_2/2016h28a_fe_pm_qs.pdf
問題の概要
ジョブスケジューリングに関する問題です。問題文長くて難しそうに見えますが、設問は穴埋めと実行結果を問うものだけですので、プログラムの説明とプログラムを照らし合わせて考えていけば解けます。
スポンサーリンク
設問1
設問1は穴埋め問題です。
早速穴埋めする箇所のプログラムを見てみましょう。
[ a ]は下記↓部分になります。ここの部分は、[プログラム1の説明]の(5) – ③で説明されている部分になります。
青枠は「i+1番目に開発作業を実施する対象サブシステム job[job_sch[i]] と i+2番目に開発作業を実施する対象サブシステム job[job_sch[i+1]] の開発作業を、順序どおりに実施した場合の二つの対象サブシステムの遅延日数の合計 wt_a」を求める処理になります。
緑枠は「i+1番目に開発作業を実施する対象サブシステム job[job_sch[i]] と i+2番目に開発作業を実施する対象サブシステム job[job_sch[i+1]] の開発作業を、順序を入れ替えて実施した場合の二つの対象サブシステムの遅延日数の合計 wt_b」を求める処理になります。
つまり、青枠側では
job[job_sch[i]] → job[job_sch[i+1]]
の順で作業した場合の遅延日数の合計を求めることになります。
job_sch[ ]の添字はi+jとなっています。jはループにより0 → 1と変化します。プログラム的にも
job[job_sch[i]] → job[job_sch[i+1]]
となるのが分かると思います。
一方、緑枠側では
job[job_sch[i+1]] → job[job_sch[i]]
の順で作業した場合の遅延日数の合計を求めることになります。
これを実現するためのjob_sch[ ]の添字が[ a ]の答えとなります。
ループによりjは0 → 1となるので、jが0の時にi+1となり、jが1の時にiとなる式が緑枠のjob_sch[ ]の添字と考えられ、これはi-j+1のときに満たします。ですので[ a ]の答えはi-j+1です。
続いて[ b ]、[ c ]、[ d ]を見ていきましょう。下記のプログラムを考えることで解くことができます。この部分は[プログラム1の説明]の(5) – ④および(5) – ⑤で説明されている処理を実行する部分です。
青枠部分では(5) – ④に書いてある通り開発作業順序の入れ替えを行なっています。何と何の順序を入れ替えているかは(5) – ③を読めば理解できると思います。job_sch[i]とjob_sch[i+1]の作業順序の入れ替えを行なっています。ですのでjob_sch[ ]の添字にはiもしくはi+1が使用されます。iは既に使用されているので、[ b ]にはもう一方のi+1を使用する必要があります。
したがって[ b ]の答えはi+1となります。
[ c ]が使用されている緑枠部分のプログラムは、入れ替えを行い、かつ、iが0でない時の処理になります。このプログラムについては[プログラム1の説明]の(5) – ⑤で説明が行われており、iを1減らす処理を行う処理になります。ここから考えると、選択肢から[ c ]はi–もしくは–iが当てはまりそうです。この2つの違いをまず整理しておきましょう。
・i–
i–が使用されている部分はiとして処理されます。その後にiの値が1減らされます。イメージとしては下記のような感じです。
y = x + (i--);
↓下記と同じ動き
y = x + i;
i = i - 1;
・–i
–iが使用されている部分はi-1として処理されます。つまりその処理実行前ににiの値が1減らされます。イメージとしては下記のような感じです。
y = x + (--i);
↓下記と同じ動き
i = i - 1;
y = x + i;
また、このプログラムではftに対する処理が行われています。ここでftが何であるかをみてみましょう。ftについては[プログラム1の説明]の(6)で説明されており、「i番目の対象サブシステムの開発作業が終わるまでの開発作業日数の合計」であることがわかります。
緑枠ではiが1減らされるため、ftは「i番目の対象サブシステムの開発作業が終わるまでの開発作業日数の合計」ではなく「i-1番目の対象サブシステムの開発作業が終わるまでの開発作業日数の合計」に更新する必要があり、そのために緑枠内でftを減らす作業を行なっています。
減らす量は「i番目の対象サブシステムの開発作業日数」ですね。
ただしここは少しひっかけで、緑の直前のでjob_sch[i+1]とjob_sch[i]の入れ替えが行われています。そのため緑枠では、プログラム的には「i-1番目の対象サブシステムの開発作業日数」をftから引いてやるのがftの意味に合っていると考えられます。
ですので、ftからは「i-1番目の対象サブシステムの開発作業日数」を減らすことと、緑枠内でiを1減らす必要があること、i–と–iの違いを考慮すると、[ c ]にはi-1としてftの減算が行われる–iを使用する必要があります。したがって、[ c ]の答えは–iとなります。
オレンジ枠の処理の説明は[プログラム1の説明]の(5) – ⑥で行われており、緑枠とは逆にiを1増やす処理を行います。
またftの説明から考えるとftは「i番目の対象サブシステムの開発作業が終わるまでの開発作業日数の合計」から「i+1番目の対象サブシステムの開発作業が終わるまでの開発作業日数の合計」に更新する必要があります。
この更新は「i番目の対象サブシステムの開発作業が終わるまでの開発作業日数の合計」に「i+1番目の対象サブシステムの開発作業日数」を足してやれば良いため、[ d ]の答えは+=となります。
設問2
設問2は実例に合わせてプログラムを動作させた時の動きを追っていく問題になります。
3行目の出力結果について問われていますので、iが0、1、2の時の処理までを追っていけば設問2を解くことができます。
それぞれのiの時のjob_sch[i]、ft、wt、wt_sumの値を実際に追っていきましょう。プログラムに出てくるjob_sch[i]に関しては図2から、job_sch[i]それぞれのjob_termとtarget_termは図1から値を取得することができます。
・i=0
job_sch[0]:0
ft:25 (0 + 25)
wt:0 (25 > 27が不成立のため)
wt_sum:0 (25 > 27が不成立のため更新なし)
・i=1
job_sch[1]:2
ft:46 (25 + 21)
wt:16 (46 – 30)
wt_sum:16 (0 + 16)
・i=2
job_sch[2]:1
ft:73 (46 + 27)
wt:44 (73 – 29)
wt_sum:60 (16 + 44)
解いてみた感想
問題自体は簡単でした。ただi–と–iの違いを理解しておく必要があったりしたので、問題を解くのにC言語の知識はやはり必要ですね。
何年分か実際に解いて感じたのですが、設問に答えるだけであればプログラムの全体像やプログラムでやろうとしていることをはっきり理解しておく必要はないですね。
この設問1を解く際にも示した考え方の通り、特に穴埋め問題に関してはまずプログラムの説明全部を読むのではなく、
- その穴埋めする必要のあるプログラム部分を探す
- 次にそのプログラム部分の説明している箇所を探す
のやり方が解くのが早いです。プログラム全体を見るのではなく問われている部分のみを局所的に理解してやれば解けるケースが大半です。
その説明で分からない単語や変数が出てきたら、次にそれらを説明している部分を探す。逆引きしながら解いていく感じで良いと思います。
★オススメページ★
下記ページから他の回の解説もたどれます。他の回のC言語問題の解き方がわからない場合は是非読んでみてください!
本ページの図・プログラム・問題文について
図やプログラム、問題文はIPA公開の過去問題から引用しています。また図やプログラムに関しては説明に必要な部分に関してのみ加工して使用させていただいております。
出典:平成28年度 秋期 基本情報技術者試験(FE)試験区分 午後 問9