c言語です!
コインをn回振った時に、連続した表の最大数がm
回以上の確率を書き出せ。
n=4の出力を、提出するソースコードの末尾に注釈として挿入せよ。
例)n=3の時
m, m回以上連続で表となる確率
0, 100.0%
1, 87.5%
2, 37.5%
3, 12.5%
という問題が出たのですがどなたか教えていただきたいです。
手も足も出ないです。。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/10/31 07:03 編集
2022/10/31 07:03
2022/10/31 07:21
2022/10/31 07:25 編集
回答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
総合スコア5444
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
総合スコア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総合スコア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総合スコア11656
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。