赤,青,黄,緑の1x2の大きさのブロックが,それぞれ3個ずつ合計12個ある。

これを5x5の矩形に重ならないように配置する。縦,横どの列を見ても同じ色のブロックが2個以上無いように配置するにはどうすれば良いか?

ブロックを縦置き,横置きの2通り考えると5x5の矩形に約25x2=50通り(実際は40通り)の置き方がある。
同じ色のブロックが3個あるから,それを配置する場合の数は約40x40x40(64,000)通り。
虱潰すことを考えると4色あるので,64,0004(16777216000000000000)通り。
実用的でないので,仕様に沿った制約を組む。
同じ色のブロックを矩形に配置するとき,40x40x40でなく,同じ色のブロックが同一列上に2個以上無いようにする。

例えば上図で×の配置は出来ない。
この絞り込み部分のプログラムは以下のようになる。
// まず,5x5の矩形にビットを割り当てる。
int bits[5][5];
for( row=0; row< 5; row++) {
for( col=0; col< 5; col++) {
bits[row][col] = bit;
bit<<=1;
}
}
// ブロックをビットで表現する。
// ブロックの置き方は,25カ所に縦,横の2通りの置き方があるので,高々25x2通り=50通り。
int color[50]; // 高々50通りの置き方がある
int ncolor = 0;
for( row=0; row< 5; row++) {
for( col=0; col< 5; col++) {
if( exist(row+0,col+1)) { // 横置き
color[ncolor++] = bits[row][col] | bits[row+0][col+1];
}
if( exist(row+1,col+0)) { // 縦置き
color[ncolor++] = bits[row][col] | bits[row+1][col+0];
}
}
}
// 全部でncolor通りの置き方があった。
// 今度は,ncolor通りの置き方を3つ組み合わせた置き方がいくつあるか調べる。
// 同じ色のブロックが3個あるので。最大ncolor*ncolor*ncolor通りの置き方がある。
int* pattern = new int[ncolor*ncolor*ncolor];
int npattern = 0; // 実際に何通りの置き方があるか。
for( i=0; i< ncolor; i++) {
for( j=i+1; j< ncolor; j++) {
for( k=j+1; k< ncolor; k++) {
if( (color[i] & color[j]) ||
(color[j] & color[k]) ||
(color[i] & color[k])) {
// ブロック同士が重なっている。同じ位置に置けない
continue;
}
// 同じ行,列に置けない。
if( samerc( color[i], color[j], color[k])) continue;
// 5x5の矩形に同じ色の3個のブロックを置けた。
pattern[npattern] = color[i] | color[j] | color[k];
npattern++;
}
}
}
実際に求めてみるとnpatternが144になる。ここから先は虱潰しても大したことは無い。
// ブロック3個を5x5に置く場合の数は全部でnpatternある。
int colorA, colorAB, colorABC, colorABCD;
int a,b,c,d;
// この組み合わせで互いに重ならないように置けるか調べる。
for( a=0; a< npattern; a++) {
colorA = pattern[a];
for( b=a+1; b< npattern; b++) {
if( colorA & pattern[b]) continue;
colorAB = colorA | pattern[b];
for( c=b+1; c< npattern; c++) {
if( colorAB & pattern[c]) continue;
colorABC = colorAB | pattern[c];
for( d=c+1; d< npattern; d++) {
if( colorABC & pattern[d]) continue;
colorABCD = colorABC | pattern[d];
// Find
}
}
}
}
結果,2件が出力されました。向きが違うだけなので実質1件。
木曜夜中にフジテレビで「コマネチ大学数学科」という番組をやっている。結構面白いと思う。
解速度
即