• ベストアンサー

選んだ整数は何? (C++)

1から100までの整数をUserに選ばせ、Userに、「選んだ数字はXX以上ですか?」と質問を繰り返し、最後にUserの選んだ数字を当てるという課題に取り組んでいます。(Userはそれに対してYes/Noでしか答えられません。) たとえば、Userが「45」を選んだとすると、「選んだ数字は50以上ですか?」というダイアログが表示され、「NO」と答えると、次に「選んだ数字は25ですか?」というダイアログが表示されて、その番号を絞ってくというものです。 これを取り組みはじめましたが、数学が弱いのでどんな式を使うのか混乱しています。数字を2づつ割っていくことはわかるのですが、50を2で割ると25で, 一方はそれを足し(50+25)、一方はそれを50から引いて(50-25)、また次に、たとえば例にだした45の場合なら(50-25+12.5,)(50-25+12.5-6.25)などなど、繰り返してくやり方がわかりません。 これは、switch文でyes/no選択させて、前後に式をいれたりするのでしょうか? このプログラミングの構成をどうするのかわからないので、ヒントをいただけないでしょうか? 

  • lilno
  • お礼率22% (6/27)

質問者が選んだベストアンサー

  • ベストアンサー
  • Fooky
  • ベストアンサー率71% (59/82)
回答No.3

補足です。 省略して書いたために曖昧になってしまったかも知れませんね。 あのアルゴリズムでは、完全に絞り込まなくても、偶然に当たってしまうことがある (例えば、ユーザが50を選んだら、初期設定の段階でコンピュータ側の予測が当たって ますよね)ので、毎回、「当たっているか」を質問し、外れている場合だけ、「上か下か」 の質問をするようになっています。 ステップ1が、当たりかどうか(変数estが選んだ数と同じか)を尋ねる質問です。 ステップ2が、選んだ数が変数estより上か下かを尋ねる質問になっています。 別の手としては、そんなことを考えずに、max == est == minになるまで ひたすら絞り込む、というのもありです。その場合、ステップ1の質問は不要です。 ステップ1を、以下のように変更すればOKです。 ステップ1:  max == min ならば、estを出力して終了。  違うなら、ステップ2へ。 数学が苦手ということなので、少し解説すると、ユーザが選んだ数は、min以上 max以下の範囲にあります。で、estはmaxとminの平均なので、max == minならば、 自動的にmax == min == estであり、選んだ数はmin以下max以上であるため、 その数が正解となります。 そうすると、以下のように書き直した方が分かり易いですね。 どちらにしても、ステップ1はいわゆる終了判定(どうなったときにプログラムを 終了させるか、即ち、どうなったら正解とみなすかの判定)です。 初期設定:  int max = 100;  int min = 1; ステップ1:  int est = (max + min) / 2; ステップ2:  min == maxならば、estを出力して終了。  違うならステップ3へ。 ステップ3:  est以上ですか?と聞く。  Yesならステップ4へ。  Noならステップ5へ。 ステップ4:  min = est;  ステップ1へ。 ステップ5:  max = est - 1;  //訂正:est以上でない = est - 1以下  ステップ1へ。    //なので、estから1引いたものをmaxとすべき

lilno
質問者

お礼

わかりやすいご説明ありがとうございました。頑張って取り組んでみます! なにぶん初心者なので、ちょっと複雑な課題が出されると、いつも途中でつまずいてわからなくなってしまうので、本当にありがたい限りです。また、なにかあればよろしくお願いします。

その他の回答 (2)

  • Fooky
  • ベストアンサー率71% (59/82)
回答No.2

上限・下限を記憶しておく変数を設ければ良いのでは? switchかifかはご自由に。Yes/Noみたいな2択 なら普通、if/elseでいいと思いますが。 初期設定:  int max = 100;  int min = 1; int est = 50; ステップ1:  estですか?と聞く。  Yesなら終了。  Noならステップ2へ。 ステップ2:  est以上ですか?と聞く。  Yesならステップ3へ。  Noならステップ4へ。 ステップ3:  min = est;  est += (max - est)/2;  ステップ1へ。 ステップ4:  max = est;  est -= (est - min)/2;  ステップ1へ。

lilno
質問者

補足

あほな質問かもしれませんが、「ステップ1でYesなら終了」という部分ですが、もし、Userが50以上の数を選び、たとえば60を選んだとします。そのUserは一番初めの「50以上ですか?」という質問に対して「Yes」と答えたら、終わってしまうことになるんでしょうか?お返事ください。 

  • y_oku
  • ベストアンサー率62% (25/40)
回答No.1

c++の処理系を持っていないので、perlで同等の構造のものをつくってみました。 c++と違うところは、動作を想像してみてください(^^;) ま、参考にはなるかと……。 12.5になるところでcelr/floor(切り上げと切り捨て)を 数値以上のとき未満のときによって、 うまく使いわけるといいのではないかと思います。 境界条件の設定をあまり考えてないので、 100以上やマイナスになったりしますがご愛敬。 ------------------------------------------------------- use POSIX; $cur_num=50; $last_num=100;; while(1){ print "選んだ数字は",$cur_num,"以上ですか?\n"; $key=<STDIN>; $tmp_num=$cur_num; if($key =~ /^y/){ last if($last_num-$cur_num==1); # 抜ける。 $tmp_num += ceil(abs($tmp_num-$last_num)/2); }else{ $tmp_num -= floor(abs($tmp_num-$last_num)/2); $tmp_num-- if $cur_num == $tmp_num; } $last_num=$cur_num; $cur_num=$tmp_num; } print "答えは", $cur_num, "です。\n"; -------------------------------------------------------

lilno
質問者

お礼

perlはやったことないのですが、y_oku さんのご意見参考にさせていただきます。アドバイスありがとうございます。

関連するQ&A

  • Yesならこっちへ、NOならあっちへ(c++)

    取り組んでる課題で、Yとタイプしたら1のステップにいけて、Nとタイプしたら2のステップに行くというところでわからなくなってしまいました。Userにそういう選択させるのには何をどう書いたらいいのですか? --------------------------------------------------------------------- 問題:1から100までの整数をUserに選ばせ、Userに、「選んだ数字はXX以上ですか?」と質問を繰り返し、最後にUserの選んだ数字を当てるという課題です。(Userはそれに対してYes/Noでしか答えられません。) --------------------------------------------------------------------- int max=100; int min=0; int mid, x; int systemtype=y, sytemtype=n; main(){ while(1){ cout<<"1から100までで好きな数字を選んでね。"; cin>> x; if (n<=0 || n>=100){ break; } if (mid == (max + min)/2){ cout<<"選んだ数字は :" << mid << " より大きい? "<< endl; cout<<" y は YES, n は NO :" << endl; } else if(min == max){ cout<<"その数字は" << x <<endl; break; } else if(min == mid){ mid += ( max - mid)/2; cout<<"あなたの選んだ数は :" << mid <<" より大きい? "<<endl; } else if(max == mid){ mid -= (mid - min)/2; cout<<"あなたの選んだ数は:" << mid << " より大きい? "<< endl; } else cout<<"その数字は :"<< n <<endl; } return 0; }

  • C言語のプログラミングについてです><

    今C言語のプログラミングの勉強をしているのですが、わからないプログラムがでてきたので教えてくださる方がいらっしゃれば、ご教授願いたいです。 数当てゲームの作成 1~9(0は除く)のなかから4つの異なる数字をランダムで選択し、4桁の数をつくる。ユーザは4つの数字の並びを入力して、作られた数を当てる。 ユーザの入力した数と作られた数を比較して、同じ数字が同じ桁にある場合は"Hit"というヒントを与える。また、同じ数字が異なる桁にある場合は"Blow"というヒントを与える。すなわち、作られた数が5849で、ユーザが4829という数値を入力した場合、"2 Hit 1 Blow"というヒントが表示されるようにする。 ユーザは10回まで、入力するチャンスが与えられる。 といった感じのプログラミングなんですが、C言語初心者である自分にはまったくわかりません; ; どなたかわかる方がいらっしゃれば、助けていただけないでしょうか?よろしくお願いします!

  • C言語の問題です。何卒ご教示願います。10個の整数

    C言語の問題です。何卒ご教示願います。10個の整数を入力し配列に保存した後、入力された数字の中に5の倍数が含まれているかを調べ、 含まれていた時には「5の倍数が含まれています」含まれていない時に「5の倍数が含まれていません」と表示させなさい。 なるべく早急にお願い申し上げます。 お手数ですが一からプログラミングを作成お願いします (たとえば♯include<stdio.h>からreturn 0;}とか)

  • チェックボックスの合計値の取得

     ACCESSとVBを使ってプログラミングを行っているのですが、チェックボックスの合計値の取得をしたいのですが、同じ行のチェックボックスをクリックする度に碁合計値がズレてしまい、困っています。  どなたか解決方法をお教えください。 例:1行 □YES □NO   YES合計 XX個   2行 □YES □NO    NO合計 XX個       :   30行□YES □NO

  • CLIQUE問題

    学校でなのですが、学校カテゴリでプログラミングの質問をするところがないので質問します。 入力にあるグラフGと整数kが与えられています。 GがkCliqueならYes, 違うならNoを返すプログラムを考えろ。 というのが問題なのですが、教科書にヒントすらのっていず、 困っています。 回答としては、文字で説明すればいいみたいです。 どのような理論を展開すればいいのかわかりませんので、 誰か教えてください。

  • 間違いを指摘して頂けませんか?(切実)

    私は大学で春からプログラミングの基礎を学び始めたプログラミング初心者です。 今、if関数のネストについて習っていて、if関数のネストを利用したプログラム作成の課題が出て、一応書いてはみたのですがどうしても上手くいきません。下に課題の内容と私の書いたプログラムを書いておきますので、間違っている箇所を指摘、修正して貰えませんか?宜しくお願い致します。 【課題】 次の項目に従ってプログラムを作成せよ。 (1)整数型の変数noを宣言 (2)「整数を入力してください。」と表示して改行 (3)キーボードから入力された値を変数noに代入 (4)入力された値が ・偶数で4で割り切れる数なら「整数○は偶数で4で割り切れます。」 ・偶数で4で割り切れない数なら「整数○は偶数だけど4で割り切れません。」 ・奇数で3で割り切れる数なら「整数○は奇数で3で割り切れます。」 ・奇数で3で割り切れない数なら「整数○は奇数だけど3で割り切れません。」 の○の位置にnoの値を当てはめて表示した後、改行 #include <stdio.h> main(void) { int no; printf("整数を入力してください。\n"); scanf("%d",&no); if(no/2==0,no%4==0){ printf("整数%dは偶数で4で割り切れます。\n",no); }else{ if(no/2==0,no%4!==0){ printf("整数%dは偶数だけど4で割り切れません。\n",no); }else{ if(no/2!=0,no%3==0){ printf("整数%dは奇数で3で割り切れます。\n",no); }else{ printf("整数%dは奇数だけど3で割り切れません。\n",no); } } } } ※なお、上のプログラムは全て左詰めになってしまっていますが、質問する上で表示出来なかっただけですので…実際にはちゃんと然るべき箇所にTabキーによる余白は入れてあります。

  • ダイアログボックスに表示されるラベル

    警告ダイアログボックスに表示して、confirmを使用すると「OK」と「キャンセル」とダイアログが表示されますが、 これを「YES」「No」というダイアログに変更したいです。 confirmは「OK」「キャンセル」のメッセージの変更はできないようですが、何かよい方法で「YES」「No」を表示できる方法、どなたか知りませんか?

  • 数学A

    6個の数字0,1,2,3,4,5を使ってできる、次のような整数は何個あるか。 ただし、同じ数字は2度以上使わないとする。 [問]6桁の整数で5の倍数 [解](式)5!+4×4!=216(個) なぜこの式になるのでしょうか?

  • 次の整数の問題の解説をお願いします

    問題 任意の正の整数nに対して,次の(A)と(B)をともに満たす正の整数Nが存在することを示せ. (A)Nはn桁であり,各桁の数字は3または8である。 (B)Nは2^nで割り切れる。 数学的帰納法で解くと思うのですが、漸化式がどうもたちません。 お願いします。

  • 正規表現を用いた整数、少数のチェック

    どうかご教授下さい。 現在JavaScriptによるプログラミングを行っています。 テキストボックスから入力された年齢、身長の値を 正規表現を用いて下記の条件をチェックしようとしていますが上手くいきません。 [条件] ●年齢● 0以上の整数。 半角数字。 0以外の頭に0が来る数字は許可しない。(例:00、012) ●身長● 0より大きい整数または少数。 半角数字、小数点。 整数の場合0以外の頭に0が来る数字は許可しない。(例:00、012) 少数の場合最下位の数字は小数点、0以外のものである。 [現状] ●年齢● 半角数字があれば半角数字以外を許可してしまう。(例:a1、1あ) 0以外の頭に0が来る数字を許可してしまう。(例:00、012) ●身長● 0以外の数字があれば最下位の数字が0でも許可してしまう。(例:123.0) 2つ以上の小数点を許可してしまう。(例:12.3.4、12..3) 上記以外にも自分で気付いていない問題があるかもしれませんが どうか助言頂きたく思います。 宜しくお願いします。 if(age.match(/(0|[1-9][0-9]*)/)){} else{ alert("年齢を半角数字で入力してください。"); } if(height.match(/([1-9][0-9]*|[0-9]+([\.][0-9]+)?[1-9]$)/)){} else{ alert("身長を半角数字で正しく入力してください。"); }

専門家に質問してみよう