情報処理Ⅱ 2004年11月16日(火) レポート課題1の解説 一言で表現 する訓練を! 解説(1) これは何をするプログラムか? 二つのコップから,決められた量の水をくみ取るプログラム Cup A Cup B 0L 0L 7L 0L 2L 5L 2L 0L 0L 2L 1L 5L 2 解説(2) 宣言されている変数の意味・用途は何か? max_a: カップAの容積 max_b: カップBの容積 goal: くみ取りたい水の量 a: カップAに入っている水の量.a == goalとなれば成功 b: カップBに入っている水の量 tmp: max_aとmax_bの値を交換するための一時変数 3 解説(3) 変数の初期値をどのようにしたときに「There is no answer.」と出力するか? 以下のいずれかを満たすとき • max_a < goal && max_b < goal が真 • goalが,max_aとmax_bの最大公約数の倍数でない 例 • max_a = 15; max_b = 9; goal = 18; ⇒ 「There is no answer.」 • max_a = 15; max_b = 9; goal = 4; ⇒ 「There is no answer.」 • max_a = 15; max_b = 9; goal = 3; ⇒ 「Cup A holds exactly 3L.」 4 解説(4) if (max_a < max_b) { ... } は何をしているか? これがないと,どんなとき(変数の初期値)に不都合が起こる か? max_aとmax_bの値を交換している. これがないと,max_a < goal && goal <= max_bが真 のとき(例えばmax_a = 5; max_b = 7; goal = 6;)に も,a == goalが真になることはなく,「There is no answer.」と出力してしまう. 5 解説(5) breakを使うことなく,同じ動作をするよう書き換えることは できるか? 変更前: while (1) { if (a == goal) { break; } else if (a == 0) { 変更後: while (a != goal) { if (a == 0) { 6 他の答案 「There is no answer.」の条件 × a = b ≠ goal に途中でなるもの × a,bが偶数,goalが奇数 × max_aがmax_bの倍数であり,goalがmax_bの倍数でな いとき 7 他の答案 max_aとmax_bの値交換の必要性 △ max_a = 0のとき不都合 △ max_a < max_bのとき不都合が起こる × max_a < max_bのとき,カップAの中身がカップBに入り 切らない • max_a = 5; max_b = 7; とし,交換のif文を除去し てコンパイル・実行すれば,不都合ないことがわかる ! max_a = 0のときに無限ループを回避できる • max_aやmax_bが0以下の場合は,このプログラムでは考 慮していなかった! 8 他の答案 break除去の方法 ○ goto文を使用する ○ break; を消して,print(...); exit(0); • いずれも「同じ動作」になるが,行儀のよい使い方ではない × while (1) { if (a == goal) { break; } while (a != goal) { elseを消し 忘れている! 9 気になったレポート 提出年月日がない 長い1段落のみで記述している 1枚のレポートにステープラ(の針)をつけている 1枚なら不要 ステープラ(の針)2つで綴じる 段落を分け,見出しをつけるなどしてわかりやすい「文章」を 1つで十分.失敗したのなら,取り除いておく 配布資料を添付している 「ゴール」と書いたのだろうが「ブール」に見える goal=○; 丸印(「任意の値」の意味と思われる)が数字の0に見える 10 ここから先を読む人への注意 ここから先は数学的記述が多く,情報処理Ⅱという科目の趣 旨を越えている.「問題に隠された数学的性質」が気になる 人や,上記の解説で納得いかない人だけが読んで自習して ほしい. 11 解説(3)の補足 最大公約数に関する準備など max_aとmax_bの最大公約数を,以下ではgcdと書く. max_aとmax_bが互いに素 ⇔ gcd == 1 ⇔ 1,2,...,max_aの任意の量をくみ取れる 「0」は,「任意の正の整数」の倍数である.ゆえに, 「0」と「任意の正の整数n」との最大公約数は,nである. goalが,gcdの倍数でないならば,goalの分量をくみ取れ ない.これは数学的帰納法で証明できる.その帰納段では, 「aとbの値(カップAとカップBの水量)が変わるとき,変わる 前のaとbがそれぞれgcdの倍数ならば,変わった後のaとb もそれぞれgcdの倍数である」ことを示せばよい. 12 解説(3)の補足 max_aとmax_bの値を固定し,goalを様々な値にして実行 すると,くみ取れる値は,gcd, 2*gcd, ..., max_aで あり(max_aもgcdの倍数であることに注意),それ以外には ない.これは,次の二つの事実と,数式処理の能力(高校レ ベル)があれば証明できる. 「Fill Cup A.」の回数をα,「Empty Cup B.」の回数をβと すると,a+b == α*max_a-β*max_bが成り立つ. 「拡張ユークリッドの互助法」と呼ばれるアルゴリズムを用いる と,X*max_a+Y*max_b == gcdを満たす整数XとYを求める ことができる. 13
© Copyright 2025 ExpyDoc