勝ち点が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;
}