• 締切済み

解説をお願いします

解説をお願いします。 次のプログラミングの解説をお願いします。 #include<stdio.h> int main(void) int n,m,x; char my_turn; printf("最後にタバスコを取った側がピザを食べます\n"); printf("タバスコの数?"); scanf("%d",&n); printf("1回にタバスコを振れる最大の数?"); scanf("%d",&m); if(n < 1 || m < 1) return 0;//負数の入力を拒否します for(my_turn = 1; n!=0; my_turn ^=1){ *1 if(my_turn){ x = (n - 1)%(m + 1);//なぜこの様な式になるのかを特に教えてください。 if(x == 0) x =1; printf("私は %d 回タバスコを振ります\n",x); }else do{ printf("何回振りますか?"); scanf("%d",&x); }while(x <= 0 || x > m || x > n); n = n - x; printf("残りは %d 回です\n",n); } if(my_turn) printf("あなたの負けです\nおいしく召し上がれ"); else printf("私の負けです\nいただきます"); return 0; }

noname#121479
noname#121479

みんなの回答

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.1

> x = (n - 1)%(m + 1);//なぜこの様な式になるのかを特に教えてください。 この部分の計算の意味がわからないということでしょうか? だとしたら、これはC言語の問題ではなく、思考ルーチンの問題です。 例えば、「1回にタバスコを振れる最大の数」が3だとします。 このとき、 ・残り5滴にして相手に回せば、必勝です。   ・相手が1滴振ったら、こちらは3滴振ることで、残り1滴になり、相手が最後のタバスコを取る羽目になる。   ・相手が2滴振ったら、こちらは2滴振ることで、残り1滴になり、相手が最後のタバスコを取る羽目になる。   ・相手が3滴振ったら、こちらは1滴振ることで、残り1滴になり、相手が最後のタバスコを取る羽目になる。 ・残り9滴にして相手に回せば、必勝です。   ・相手が1滴振ったら、こちらは3滴振ることで、残り5滴になる。   ・相手が2滴振ったら、こちらは2滴振ることで、残り5滴になる。   ・相手が3滴振ったら、こちらは1滴振ることで、残り5滴になる。 ・以下、残数が「4の倍数+1」滴にして相手に回せば、必勝です。 このとき、選ぶべき滴数を式にするならば、「(残りの滴数-1)を4で割った余り」の滴数選べば必勝ということになります。 (残り10滴なら、(10-1)=9を4で割った余りである1滴を選ぶと、残り9滴になる) さらに、一回に取れる滴数の最大値を3滴で説明しましたが、一般的に言うと、 「(残りの滴数-1)を(一回の最大滴数+1)で割った余り」を選べばいいということになります。 それを式にすると、「(n - 1)%(m + 1)」になります。

関連するQ&A

  • 解説をお願いします。

    どこを変えればよいのでしょうか? #include<stdio.h> int main(void) int n,m,x; char my_turn; printf("最後にタバスコを取った側がピザを食べます\n"); printf("タバスコの数?"); scanf("%d",&n); printf("1回にタバスコを振れる最大の数?"); scanf("%d",&m); if(n < 1 || m < 1) return 0;//負数の入力を拒否します for(my_turn = 1; n!=0; my_turn ^=1){ *1 if(my_turn){ x = (n - 1)%(m + 1);//なぜこの様な式になるのかを特に教えてください。 if(x == 0) x =1; printf("私は %d 回タバスコを振ります\n",x); }else do{ printf("何回振りますか?"); scanf("%d",&x); }while(x <= 0 || x > m || x > n); n = n - x; printf("残りは %d 回です\n",n); } if(my_turn) printf("あなたの負けです\nおいしく召し上がれ"); else printf("私の負けです\nいただきます"); return 0; } 問題の条件を入力した瞬間に,先手か後手かどちらか必勝かが分かります. そこで,先手必勝の場合はコンピュータが先手を選択し,後手必勝の場合は,コン ピュータは必ず後手を勝手に選択する処理を追加し,人間がコンピュータに絶対に 勝てないプログラムに変更する、

  • フローチャートについての質問です

    #include <stdio.h> int main(void) { int n1, n2, n3; printf ("数値1: "); scanf ("%d",&n1); if (n1%2==1){ printf ("数値1は奇数\n"); } else { printf ("数値1は偶数\n"); } printf ("数値2: "); scanf ("%d ",&n2); printf ("数値3: "); scanf ("%d",&n3); if (n2 > n3) printf ("数値2の方が数値3より大きい\n"); else if (n2 < n3) printf("数値2より数値3の方が大きい\n"); else printf("数値2と数値3は等しい\n"); return 0; } をフローチャートに直したいのですが方法が解りませんどなたか親切なかたお教えください JIS規格のものでお願いします

  • このプログラミングで。

    #include <stdio.h> int main(void) { int x; printf("長い河はどれ?\n 1天の川 2三途の川 3谷川\n"); scanf("%d",&x); if(x == 1){ printf("なるほど"); } else if(x == 2){ printf("フーン"); } else if(x == 3){ printf("やっぱり?"); } else if(x != 1){ printf("ハァ?"); } else if(x != 2){ printf("ハァ?"); } else if(x != 3){ printf("ハァ?"); } return 0; } これを実行して 等しくないときハァ?と表示させて、ふたたび、入力をさせる方法を教えてください。何度でも入力を求める方法もありましたら教えていただきたいです。 とても理解に苦しむような質問ですがよろしくおねがいします。

  • アッケルマン関数

    アッケルマン関数 ack(m,n)={ n+1 m=0のとき      { ack(m-1,1) m>0,n=0のとき { ack(m-1,ack(m,n-1)) m>0,n>0のとき をプログラムしたいのですが、再帰を使ったプログラムがうまく実行できません。どこがいけないのでしょうか? #include<stdio.h> int m,n; int ack(int m, int n) { if (m = 0) return n + 1; if ((m > 0) && (n = 0)) return ack(m - 1, 1); else return ack(m - 1, ack(m, n - 1)); } main() { int m,n; printf("アッケルマン関数ack(m,n)を計算します。\n"); printf("自然数m,nを入力してください\n"); scanf("%d",&m); scanf("%d",&n); printf("アッケルマン関数ack(%d,%d)の値は%dです。\n", m, n, ack(m,n)); }

  • C言語について

    次のような問題です。 問 自然数nを入力し、nを3で割って割り切れるかどうかを判定し結果を表示する。「割り切れる」、「1余る」、「「2余る」のいずれかが入るものとする。 このようなものをつくりました。 #include<stdio.h> int main(void) { int n; printf("自然数:"); scanf("%d",&n); if(n==0){ printf("割り切れる\n"); }else if(n==1){ printf("1余る\n"); }else{ printf("2余る"); } return(0); } これで合っているかよろしくお願いします。

  • このプログラム見てください

    これで動いたと書いてあるのに動きません。 どこを直せば良いのか教えてください。 #include <stdio.h> int combination(int n,int r){ if ( r==0 ){ return 1; }else if( r==n ){ return 1; }else{ return (combination(n-1,r-1)+combination(n-1,r)); } } int main(){ int num_n=0; int num_r=0; int answer=0; printf("組み合わせの計算をします。数値を入力してください。N=?。\n"); printf("[n]:"); scanf("%d",&num_n); rewind(stdin); printf("[r]:"); scanf("%d",&num_r); rewind(stdin); answer=combination(num_n,num_r); printf("%dC%d=%d\n" , num_n, num_r, answer); return 0; }

  • C言語なんですがうまくうごきません。

    X=1においてX^nをm回微分した値を求めるプログラムを作っているのですが、 何度も考えて訂正したりしてるのですが、どこが悪いのかわかりません 再帰関数を使ってます。 デバッグして調べてみてるのですが、うまくいってるようにみえるのですが、最後の値が0になります。 nを大きい値にすると、マイナスになったりするんです。 よくわかりません。 ちなみにnとmは正で、mは10までの数を入力します。 このプログラムの基本形を変えないで問題改善することはできるのでしょうか? わかる人いましたら教えてください。 #include <stdio.h> double differentiate(double n, int m); int main(void) { int a, b; printf("Input 2 number\n"); fflush(stdout); scanf("%d %d", &a, &b); printf( "a = %d\nb = %d\n", a, b ); printf("Answer = %d\n", differentiate(a, b)); return 0; } } double differentiate(double n, int m) { if(m == 1){ return n; }else{ return n * n-1 * differentiate(n-1, m-1); } }

  • 解説お願いします。

    0から9までの数字を入力しあたりかはずれかを表示するプログラム。 #include<stdio.h> #include<time.h> #include<stdlib.h> int main(void){ int r,a; printf("0から9までの数字を入力してください。\n"); scanf("%d",&a); srandom(time(NULL)); r = random()%10; printf("%d \n",r); if(a==r){ printf("アタリ\n");} else{ printf("ハズレ\n");} return 0; } 例えば%10は何のためにあるのかとか・・

  • プログラムの練習問題をやっていたのですが、練習問題の答えのような実行結

    プログラムの練習問題をやっていたのですが、練習問題の答えのような実行結果にならないので教えていただけませんか? 下記に記したプログラムを実行すると x=9 y=-9 [ 9]*[-9]=[ -81],[ 9]*[-8]=[ -72],[ 9]*[-7]=[ -63],・・・・ ・・・・ [10]*[-9]=[ -90],[10]*[-8]=[-80],・・・・ ・・・・ のようになるのですが、 x=9 y=-9 [ 9]*[-9]=[ -81],[10]*[-9]=[-90],・・・ [ 9]*[-8]=[ -72],[10]*[-8]=[-80],・・・ [ 9]*[-7]=[ -63],・・・ ・・・・ のようにするためにはどうすればいいですか? #include <stdio.h> int main(void) { int x,y,m,n; printf("x="); scanf("%d",&x); printf("y="); scanf("%d",&y); for(m=x;m<=x+3;m++) { printf("\n"); for(n=y;n<=y+14;n++) { printf("[%2d]*[%2d]=[%4d],",m,n,m*n); } printf("\n"); } return(0); }

  • 組み合わせ

    n個の集合からp個を取る組み合わせの総数を出力するプログラムなんですが nCp=n!/p!(n-p)!という式を使い #include<stdio.h> int kaijo(int m); int comb(int n,int p); int main(void) { int i,j; printf("n="); scanf("%d",&i); printf("p="); scanf("%d",&j); printf("comb(%d,%d)=%d\n",i,j,comb(i,j)); } int kaijo(int m) { if(m>0) return(m*kaijo(m-1)); else return 1; } int comb(int n,int p) { if(n>0) return((n*kaijo(n-1))/(p*kaijo(p-1)*(n-p)*kaijo(n-p-1))); else return 1; } と書いてみたのですがこれではnが大きいとC言語のint型で扱える最大値を超えてしまい正しい結果が出力されません。  そこでint型を使ったままでnやpが大きい場合でもある程度出力できるようにしたいのですがどう改良したらよいのでしょうか? おそらくnCp=n*(n-1)*・・・*(n-p+1)/p!という式を使うのですがよく分かりません。よろしくお願いします。

専門家に質問してみよう