
APCSの例題解いてみる(2)
の続きです。
問題はこちら
8.プログラムの実行結果を問う問題。これも頭痛くなってくるな。
最初のforループでi =1から30まで回して
Q[0]=1,Q[1]=2,Q[2]=3・・・Q[29]=30,まで初期化。
forループ抜けた時点でtail =30 head=0 count=0
次のwhile文で条件tail >head + 1 実行部にhead=head+1
があるのでhead 0から28までの29回の処理を行うのかと思いきや
while文の実行部でtailをインクリメントするようなことやっていて、おいおいと思います。おまけにif文の字下げもわざと変えて混乱を誘っている。
「イケナイ見本」ばかり出てきて・・・。
tailをインクリメントしているのはcount=3のところで、3回に1回。まあ、落ち着いて解けば数値の変化を追えるかな?
もう一度。forループ抜けた時点でtail =30 head=0 count=0
val にQ配列の要素を入れ要素を一つずらして・・ってif文以外ではQの要素をいじることはしていない。count==3のとき0に戻して、valの値をQ[tail]に書き込む。(つまり3回に1回)
だいたい見えてきた。forループ終了時点で
Q[0]=1,Q[1]=2,Q[2]=3・・・Q[29]=30,tail =30 head=0 count=0
whileではQ[0],Q[1]はスルーしてQ[2]の値を末尾Q[30]として追加。なんてことを繰り返す。
Q[0]=1,Q[1]=2,Q[2]=3・・・Q[29]=30,Q[30]=3,Q[31]=6,Q[32]=9,
うむ、動きは見切った。
1 2 3 4 5 6・・・28 29 30 のあとは
3 6 9 12 15 18 21 24 27 30 ときたら次は
9 18 27 18 、までで終了。(三個飛ばしで追いかけてくる感じ?)最後は18
うん、答えは出たけど、難問奇問の類だと思う。
そもそも時間配分はというと

こんな問題を、1時間に20問解く。小問一問3分? それを第一節、第二節の2回に分けて2時間で40問解く? いやいや無理無理。自分の場合、この問題、結論に納得するまで1時間くらいかかったかも。この一問で試験時間終わっちゃうでしょう?
「全部解く」のはあきらめて、難問・奇問は捨て、必ずとれる問題を拾う、ということに徹するしかないように思います。
9.f(a)という関数は浮動小数のaを超えない最大の整数を返す。
float x=10 y=3として、0.5*x/y - f(0.5* x/y) の値が0.5より大きいか同じか小さいかで場合分けする問題。まあ、
x/y =3.33333・・だから 1.6666-1 で0.6666 条件分岐の0.5と同じでもなく、0.5未満でもない場合に当てはまるから f(0.5*x/y)+1は2になる。
一つ上の8.の問題と比べるとずっと簡単な問題。こういうのを探して先に解く、というテクニックが必要になってくるのでしょう。
10.これも楽ちんかな。与えられた関数fはx、yの入れ替えだから・・と思うと引っ掛け。f(x,y)は外へ影響しないからx,yは入れ替わっていない。それが分かっているかどうかを問うだけの問題でしょうか。整数の範囲で
( 2-3)*(2+3)/2 で-2。
11.期待通りに出力するには最小で何行修正する必要があるか?という問題。
一行にいろいろ詰め込めばできちゃうかもしれないし、出題側もミスしたくないだろうから、とりあえず最小値を選んどけばいい?(笑)
いえ、真面目に考えます。アスタリスクを一行目は1個、2行目は3個、三行目は5個という具合に、5行目まで出力。真ん中に寄せるためにアスタリスク出力の前に空白を4,3,2,1,0と入れたい。k=4 m=1が初期値
i が1から5までで、何行目かを示す。・・ループ実行部で変更されていないことを確認。
i=1のとき内側のjのループ、j=1からk(最初は4)まで回るから空白4あとは、iが増えるにつれkは3,2,1,と減っていくから問題なさそう。
次のアスタリスクを出力するループはj=1からm(最初は1)だからアスタリスク1個、i=2のときm=2だから、足りない。
m=m+1; の行をm=m+2; に修正すれば解決ということで、必要な修正は1行。
12.a[10]={1,2,9,2,5,8,4,9,6,7}の配列に対して与えられた関数fで
f(a,10)を実行する。関数fのforループはi=1から i=9まで9回まわす
a[i]>=a[index]なら index をi に置き換えるということで
index =0でi=1にきたときa[0]=1よりa[1]=3の方が大きいからindexを1に置き換え、ということを順繰りにやってa[9]=7まで比較する最後にindexが書き換えられているのはa[10]={1,2,9,2,5,8,4,9,6,7}のここだからindex =7
これも、取りこぼしたくない問題。