プロが教えるわが家の防犯対策術!

自分は麻雀の結果の集計をしていて面倒な作業があり、プログラムを組めないだろうかと考えておりますが、アルゴリズムを作成してコーディングしようにもどうやればいいのか分からないのでどうしたものかと困っております。どうしたらよいか、わかる方はどなたかお教え頂ければ助かります。

質問01.異なる16個~24個の数字があり、その中の4つの数字の和が0ずつになるようにそれぞれ分けたいのですが、どのようにすればよいでしょうか?
例えば、45、10、-25、-30、55、20、-45、-30、25、15、-10、-30、80、25、-35、-70の16個の数字があったとすれば、(45、10、-25、-30)、(55、20、-45、-30)、(25、15、-10、-30)、(80、25、-35、-70)の4つずつ4組にわけられようにできるプログラムを組みたいのです。なお、数字は整数のみで、他にも20個の場合もありますし、24個の場合もあります。

質問02.10人~20人の人数で4人ずつ麻雀卓(10~11人の場合は2つの麻雀卓、12~15人の場合は3つの麻雀卓、16人以上は4つの麻雀卓(最大4卓))に座らせて、5回戦を戦わせたいと考えております。その際には、できる限り違う人と戦わせたいとした場合、どのような組み合わせができるかをプログラムで自動的に割り出したいのですが、どのようにすればよいでしょうか?
なお、10人や11人などの人数の場合は2人余り、3人余りとなり、卓には座れず待つので、その余った人は5回戦の内1回戦えないため4回戦だけとなります。さらに、できるだけばらけた組み合わせは表などのようにわかりやすく表示できればより幸いです。

以上ですが、両方できれば最高ですが、どちらか一方でも構いませんので宜しくお願い致します。

A 回答 (4件)

一部訂正です。



for( int i = 1; i <= MEMBERS; i++ ) {
Display( i );
}



for( int i = 1; i <= ( NUM / MEMBERS ); i++ ) {
Display( i );
}

の間違いです。
    • good
    • 0
この回答へのお礼

修正の方もありがとうございました。また、他にも、色々なパターンで16個の数字を0になるように4組ずつ分けることができ、12個の場合も問題なく4組ずつわけることができました。私が考えていたように変数が多いわけではないので、これは本当に楽にできました。本当にありがとうございました。

お礼日時:2011/09/27 08:23

質問01についてですが、



( 45, 10, -25, -30 )
( 55, 20, -45, -30 )
( 25, 15, -10, -30 )
( 80, 25, -35, -70 )

の組み合わせ以外に、例えば、

( 45, 15, -30, -30 )
( 55, 20, -45, -30 )
( 25, 10, -10, -25 )
( 80, 25, -35, -70 )

の組み合わせも可能だと思うのですが、その組み合わせでもよいのなら、次のようなプログラムでもできます。( C/C++ で書きました。)

#include <stdio.h>

#define TRUE 1
#define FALSE 0

#define NUM 16
#define MEMBERS 4

int num[ NUM ] = { 80, 55, 45, 25, 25, 20, 15, 10, -10, -25, -30, -30, -30, -35, -45, -70 };
int grp[ NUM ] = { 0 };

int Search( int start, int group, int sum, int count );
void Display( int group );

int main( void )
{
Search( 0, 1, 0, 0 );

for( int i = 1; i <= MEMBERS; i++ ) {
Display( i );
}

return 0;
}

int Search( int start, int group, int sum, int count )
{
for( int i = start; i < NUM; i++ ) {
if( grp[ i ] == 0 ) {
if( count == MEMBERS - 1 ) {
if( sum + num[ i ] == 0 ) {
grp[ i ] = group;
if( group == ( NUM / MEMBERS ) ) {
return TRUE;
}
if( Search( 0, group + 1, 0, 0 ) ) {
return TRUE;
}
grp[ i ] = 0;
return FALSE;
}
} else {
grp[ i ] = group;
if( Search( i + 1, group, sum + num[i], count + 1 ) ) {
return TRUE;
}
grp[ i ] = 0;
}
}
}
return FALSE;
}

void Display( int group )
{
int count = 0;

printf( "( " );
for( int i = 0; i < NUM; i++ ) {
if( grp[ i ] == group ) {
printf( "%d", num[ i ] );
count++;
if( count < MEMBERS ) {
putchar( ',' );
putchar( ' ' );
}
}
}
puts( " )" );
}


出力結果
( 80, 25, -35, -70 )
( 55, 20, -30, -45 )
( 45, 15, -30, -30 )
( 25, 10, -10, -25 )
    • good
    • 0
この回答へのお礼

これは、本当にありがとうございました。まさか、ソースまで書いていただけるとは本当にうれしい限りです。早速、中身を解析しつつやってみます。ありがとうございました。本当に助かりましたm(_ _)m。

お礼日時:2011/09/27 05:22

#1の者です。


麻雀の競技結果の集計だから、ゼロサムになるのは当たり前でしたね。
16個、20個、24個くらいであれば、それらから4個を選ぶ組合せを
総当たりで求めてもさほど大きな数にはならないので、
愚直ではありましょうがいちばん確実だと思います。
    • good
    • 0
この回答へのお礼

愚直に、組み合わせを考えてfor文と変数を組み合わせてやっていけばいいですかね。やはり、簡単な方法はありませんよね(笑)。私も同意見だったので、愚直にやっていこうかと思います。ありがとうございました(^-^)!!

お礼日時:2011/09/24 23:07

質問01についてお聞きします。


当該の16個、20個、または24個の整数の全体の合計が0であることは
保証済みなのでしょうか。

この回答への補足

はい、それはもちろん保証済みです。合計は0になり、元々4つずつの合計が0だったものなのですが、どの4つの数字の組み合わせが0であったのかがわからなくなってしまったのです。

補足日時:2011/09/24 16:54
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!