質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

4回答

1342閲覧

コインの表裏の問題について

ionto369

総合スコア0

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2022/10/31 06:45

編集2022/10/31 07:04

c言語です!
コインをn回振った時に、連続した表の最大数がm
回以上の確率を書き出せ。
n=4の出力を、提出するソースコードの末尾に注釈として挿入せよ。

例)n=3の時
m, m回以上連続で表となる確率
0, 100.0%
1, 87.5%
2, 37.5%
3, 12.5%

という問題が出たのですがどなたか教えていただきたいです。
手も足も出ないです。。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/10/31 06:53

> c言語です! であれば質問のタグもCにすべき.
fana

2022/10/31 07:03 編集

nの値の範囲に条件が設けられていたりしますか? それとも,そういう条件とかは全くなくて,例えば「n=7億回」とか言われたら7億と1行の出力をしろ,という話なのですか? (※てきとーにふざけてるとかじゃなくて,それ次第で取り得るアプローチが違ってくる可能性がありそうだから尋ねているんだよ)
ionto369

2022/10/31 07:03

nの範囲は設けられていません。
fana

2022/10/31 07:21

(…となると,頑張ってパターンを列挙して数えるような方法だとダメなのかも.何らかの計算でぱぱっとできる方法が存在するってことなのかな?)
jimbe

2022/10/31 07:25 編集

本当に手も足も出ないのでしょうか。 main 関数は書けませんか? n=0 の時だけの表示は出来ませんか? n=1 の時だけはどうでしょうか? 組み合わせて n=4 までを if で分岐させて表示することは? とりあえず幾つかの固定状態を作って見て、そこからルールを見出すというのも方法です。
guest

回答4

0

数学的性質を利用した解だとこうなると思います。

c

1#include <stdio.h> 2 3double coin(int n, int m) { 4 if (m == 0) return 1; 5 int pattern = 1 << n; 6 int count = (2 << (n - m)) - 1; 7 return (double)count / pattern; 8} 9 10int main(void) { 11 int n = 4; 12 for (int i = 0; i <= n; ++i) { 13 printf("%d, %1.2f%%\n", i, 100 * coin(n, i)); 14 } 15}

投稿2022/10/31 10:22

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/11/01 01:21

実行してみたら n=4,m=2 の値が 43.75% と表示されましたが,これって違くないですか? 全16パターンを手作業で分類すると 0 : 1パターン 1 : 7パターン 2 : 5パターン 3 : 2パターン 4 : 1パターン なので,m=4,n=2 のときは 100.0*(5+2+1)/16 = 50[%] ではないでしょうか.
guest

0

簡単にDFS解を示しておきます.

C

1#include <stdio.h> 2#include <stdlib.h> 3 4int max(int a, int b) { 5 return a > b ? a : b; 6} 7 8void dfs(int n, int depth, int cnt, int mx_cnt, int bin, int *M) { 9 if (n == depth + 1) { 10 for (int i = 0; i <= mx_cnt; ++i) M[i]++; 11 return ; 12 } 13 dfs(n, depth + 1, 0, mx_cnt, 0, M); 14 dfs(n, depth + 1, (bin ? cnt : 0) + 1, max(mx_cnt, (bin ? cnt : 0) + 1), 1, M); 15} 16 17int main(void){ 18 int n = 4; 19 int *M = (int*)calloc(sizeof(int), n + 1); 20 dfs(n, 0, 0, 0, 0, M); 21 dfs(n, 0, 1, 1, 1, M); 22 for (int i = 0; i <= n; i++) { 23 printf("%d, %.1lf\n", i, 100.0 * M[i] / (1 << n)); 24 } 25 return 0; 26}

見てわかる通り,時間/空間計算量共にO(2^N)です.

これがもし学校の課題である場合,教師側としては掛け算も習ってない小学生が掛け算をいきなり使い出したみたいな気分になると思うので,ちゃんと自力で書かれることを推奨します.

コメントでjimbeさんがおっしゃている通り,if文を使って順に

  • n = 0におけるm = 0のとき
  • n = 1におけるm = 0のとき,m = 1のとき
  • n = 2におけるm = 0のとき,m = 1のとき,m = 2のとき
  • n = 3におけるm = 0のとき,m = 1のとき,m = 2のとき,m = 3のとき
  • n = 4におけるm = 0のとき,m = 1のとき,m = 2のとき,m = 3のとき,m = 4のとき

のようにして全列挙し,法則性を探して解析を進めることが大事です.

おそらく問題の出題意図はこの「全列挙し,法則性を探して解析をできるかどうか」にあると思われます.残念ながら私の回答は出題者の意図に沿わないものになっている可能性があること注意してください.

投稿2022/10/31 09:22

PondVillege

総合スコア1579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ありそうなビット扱い。 N は longビット数まで。

c

1#include <stdio.h> 2 3#define N 4 4 5int longestSequenceOf1(long v) { 6 int max = 0; 7 for(int c=0; v>0; v>>=1) if(v&1) max=max<++c?c:max; else c=0; 8 return max; 9} 10void research(long *a, long vmax) { 11 for(int v=0; v<vmax; v++) { 12 int max = longestSequenceOf1(v); 13 for(int i=0; i<=max; i++) a[i]++; 14 } 15} 16int main(void){ 17 long vmax = 1 << N; 18 long a[N+1] = {0}; 19 research(a, vmax); 20 printf("m, m回以上連続で表となる確率\n"); 21 for(int i=0; i<=N; i++) printf("%d, %.1f%%(%ld)\n", i, 100.0*a[i]/vmax, a[i]); 22}

plain

1m, m回以上連続で表となる確率 20, 100.0%(16) 31, 93.8%(15) 42, 50.0%(8) 53, 18.8%(3) 64, 6.2%(1)

投稿2022/10/31 09:13

編集2022/10/31 10:20
jimbe

総合スコア12646

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

nの値が小さいなら,全パターンを調べてカウントすれば良いかと…
(↓のコードはとりあえず n=0,1,2,3,4 では動作テストしました)

C

1int Next( unsigned char *Ptn, size_t n ) 2{ 3 for( size_t i=0; i<n; ++i ) 4 { 5 if( Ptn[i]==0 ){ Ptn[i]=1; return 1; } 6 Ptn[i] = 0; 7 } 8 return 0; 9} 10 11int Count( unsigned char *Ptn, size_t n ) 12{ 13 int c = 0; 14 int r = 0; 15 for( size_t i=0; i<n; ++i ) 16 { 17 if( Ptn[i] )++c; 18 else 19 { 20 if( r<c )r=c; 21 c = 0; 22 } 23 } 24 return ( r<c ? c : r ); 25} 26 27void Test( size_t n ) 28{ 29 printf( "0 : 100%%\n" ); 30 if( n == 0 )return; 31 32 size_t *Counter = (size_t*)calloc( sizeof(size_t), n ); 33 unsigned char *Ptn = (unsigned char*)calloc( sizeof(unsigned char), n ); 34 35 while( Next( Ptn, n ) ) 36 { 37 ++Counter[ Count(Ptn,n)-1 ]; 38 } 39 40 for( size_t i=0; i<n-1; ++i ) 41 { 42 for( size_t k=i+1; k<n; ++k ) 43 { Counter[i] += Counter[k]; } 44 } 45 46 double nAllPtn = pow( 2.0, n ); 47 for( size_t i=0; i<n; ++i ) 48 { 49 printf( "%u : %f%%\n", unsigned int(i+1), 100*Counter[i] / nAllPtn ); 50 } 51 52 free( Ptn ); 53 free( Counter ); 54} 55 56int main(void) 57{ 58 Test( 4 ); 59 return 0; 60}

ただ,問題について私が確認のために問うたところ,

nの値の範囲に条件が設けられていたりしますか?
それとも,そういう条件とかは全くなくて,例えば「n=7億回」とか言われたら7億と1行の出力をしろ,という話なのですか?

という問いに対して,

nの範囲は設けられていません。

とのことですので,こんな方法だとどこかで限界がくるだろうと思います.

投稿2022/10/31 08:10

編集2022/10/31 08:11
fana

総合スコア11656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/10/31 08:14

あと,出力がてきとーに printf( "%f" ); になってるので,これだと > 1, 87.5% みたく,必要な桁だけが出力される形にはならない( "87.50000" という形になる).
fana

2022/10/31 08:20

(こんな「数える」話じゃなくて,ちゃんと確率がどうのこうのいう数学な方法でやれや,という話なのだろうと思うけど……そっちは手も足も出ないっす…)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問