的の得点の配置
忘年会でダーツ投げをします。ダーツの的の得点の配置を考えることになりました。
できるだけ結果がばらつくように得点を配置するにはどうしたらよいでしょうか。
統計とか真面目に考えるつもりは無いので、とりあえず以下のような単純なプログラムを書きました。
的は 12分割されていて、各部分に得点を割り振ります。ダーツを 3回投げて、当たった部分の得点を得ます。
3 回の得点の合計が評価対象です。値が大きい順から賞がもらえます。
計算が面倒なので、各部分は等面積で、投げたダーツが全部当たるものとしました。
賞の個数は、1等から 4等までが 1個、5等が 3個、 6等が 5個、7等が 10個です。人数は 50人です。
/** * ダーツの的の得点の配置を考える */ #include <cstdio> #include <cstdlib> #include <ctime> // 固定値 enum { NINZU = 50, KAISUU = 3 }; // 人型 struct MAN { int no; double ave; }; // 比較関数。降順 int myComp( const void* a, const void* b ) { return (((MAN*)a)->ave > ((MAN*)b)->ave) ? -1 : ((((MAN*)a)->ave < ((MAN*)b)->ave) ? 1 : 0); } //////////////////////////////////// main int main(void) { int i, j; // カウンタ int tokuten[] = { 4, 8, 4, 6, 8, 1, 8, 10, 2, 8, 15, 20 }; // 的に配置する得点。これをいじる MAN m[ NINZU ]; // 人 int pickup = 0; // 引いた点数 // 乱数発生器 srand( (unsigned long)time(NULL) ); // ダーツ投げ部 for( i = 0; i < NINZU; ++i ) { // 人数分繰り返し // 初期化をここで m[ i ].no = i; m[ i ].ave = 0.0; // ダーツを投げる for( j = 0; j < KAISUU; ++j ) { // KAISUU 回投げます pickup = rand() % 12; // 的に刺さった m[ i ].ave += tokuten[ pickup ]; // 点数加算 } } // 集計 for( i = 0; i < NINZU; ++i ) { m[ i ].ave /= ((double)KAISUU); // 平均 } // ソート qsort( m, NINZU, sizeof( MAN ), &myComp ); // 結果表示 int ataricount = 0; // カウンタ int atari = 0; // 何等賞? for( i = 0; i < NINZU; ++i ) { if( ataricount == 0 ) { atari = 1; // 1等賞 } else if( ataricount == 1 ) { // 1人 atari = 2; // 2等賞 } else if( ataricount == 2 ) { // 1人 atari = 3; // 3等賞 } else if( ataricount == 3 ) { // 1人 atari = 4; // 4等賞 } else if( ataricount < 7 ) { // 3人 atari = 5; // 5等賞 } else if( ataricount < 12 ) { // 5人 atari = 6; // 6等賞 } else if( ataricount < 22 ) { // 10人 atari = 7; // 7等賞 } else { atari = 0; // ハズレ } ++ataricount; printf( "no[%2d], ave [%4.2f] (%2d)?n", m[i].no, m[i].ave, atari ); // 得点順に表示 } return 0; }
書いて何回か実行してはみたものの、よく分かりません。
最適解が求められれば良いのですが、私の頭では無理です。考えてもしょーがないって感じです。