勝ち点が11になるのは,3勝0敗2分けになることは直感で判る。
3勝2分けを前提に作ったプログラムの実行結果は以下の通り。
: ABCDEF A : ○△△○○ B : × △○○○ C : △△ △○○ D : △×△ ○○ E : ×××× ○ F : ××××× loop cnt:59049, find:1
プログラムのソースは以下の通り。重複除去は星取表の勝ち点を文字列に変換してSTLのsetで既に出現したかどうか判断する。
#include "puzutl.h" #include <math.h> set<string> dupres; // 重複結果を取り除くために利用する int star[6][6]; // 星取り表(0:勝ち点0,1:勝ち点1,3:勝ち点3を設定) int cnta[3] = { 0, 1, 3}; // 星取り表行方向の勝ち点可能性 int cntb[3] = { 3, 1, 0}; // 星取り表列方向の勝ち点可能性 struct struct_team { int katiten; // star[][]に設定した勝ち点の行合計 int idx; // 勝ち点でソートしたとき,star[][]のどの行を指していたかを記録する }team[6]; // 以下のような星取表を仮定する。 // Aチームを配列の0行目に仮定する。 // AT1T2T3T4T5 // A ○○○△△ // T1× a b c d // T2× e f g // T3× h i // T4△ j // T5△ int cmpkatiten( const void* a, const void* b) { return -(((struct_team*)a)->katiten - ((struct_team*)b)->katiten);}// 勝ち点を降順にソートする cstring stars( int v) { cstring s[] = {"×","△","*","○"}; return s[v];} YesNo isdupresult() // 重複結果か? { char buf[256]; int i=0; for( int x=0; x< 6; x++) { for( int y=0; y< 6; y++) { buf[i++] = '0'+star[team[x].idx][team[y].idx]; } } if( dupres.find(buf) != dupres.end()) { return YES; } dupres.insert(buf); return NO; } int main( int argc, cstring argv[]) { // T0チームの勝ち点は○○○△△と判るので星取り表を埋めてしまう。 star[0][1] = 3; star[0][2] = 3; star[0][3] = 3; star[0][4] = 1; star[0][5] = 1; star[1][0] = 0; star[2][0] = 0; star[3][0] = 0; star[4][0] = 1; star[5][0] = 1; int cnt = 0, find = 0; // 星取り表の残りの部分を虱潰す。 for( int a=0; a< 3; a++) { star[1][2] = cnta[a]; // 一方が勝ち点3なら star[2][1] = cntb[a]; // 反対側は勝ち点0になる。 for( int b=0; b< 3; b++) { star[1][3] = cnta[b]; star[3][1] = cntb[b]; for( int c=0; c< 3; c++) { star[1][4] = cnta[c]; star[4][1] = cntb[c]; for( int d=0; d< 3; d++) { star[1][5] = cnta[d]; star[5][1] = cntb[d]; for( int e=0; e< 3; e++) { star[2][3] = cnta[e]; star[3][2] = cntb[e]; for( int f=0; f< 3; f++) { star[2][4] = cnta[f]; star[4][2] = cntb[f]; for( int g=0; g< 3; g++) { star[2][5] = cnta[g]; star[5][2] = cntb[g]; for( int h=0; h< 3; h++) { star[3][4] = cnta[h]; star[4][3] = cntb[h]; for( int i=0; i< 3; i++) { star[3][5] = cnta[i]; star[5][3] = cntb[i]; for( int j=0; j< 3; j++) { star[4][5] = cnta[j]; star[5][4] = cntb[j]; // 各チームの勝ち点を求める。 team[0].katiten = 11; team[1].katiten = star[1][0] + star[1][1] + star[1][2] + star[1][3] + star[1][4] + star[1][5]; team[2].katiten = star[2][0] + star[2][1] + star[2][2] + star[2][3] + star[2][4] + star[2][5]; team[3].katiten = star[3][0] + star[3][1] + star[3][2] + star[3][3] + star[3][4] + star[3][5]; team[4].katiten = star[4][0] + star[4][1] + star[4][2] + star[4][3] + star[4][4] + star[4][5]; team[5].katiten = star[5][0] + star[5][1] + star[5][2] + star[5][3] + star[5][4] + star[5][5]; team[0].idx = 0; team[1].idx = 1; team[2].idx = 2; team[3].idx = 3; team[4].idx = 4; team[5].idx = 5; qsort( team, 6, sizeof(struct_team), cmpkatiten); if( team[0].katiten == 11 && team[1].katiten == 10 && team[2].katiten == 9 && team[3].katiten == 8 && team[4].katiten == 3 && team[5].katiten == 0) { if( !isdupresult()) { // 星取結果から重複を除去する。 find++; ps( " : ABCDEF\n"); for( int x=0; x< 6; x++) { ps( "%-.2s : ", "ABCDEF"+x*2); for( int y=0; y< 6; y++) { if( x == y) ps( " "); else ps( "%s", stars(star[team[x].idx][team[y].idx])); } ps( "\n"); } ps( "\n"); } } cnt++; // ここに制約処理を書く } } } } } } } } } } ps( "loop cnt:%d, find:%d\n", cnt, find); return 0; }