プログラムの実行結果は以下の通り。
Find 2件, 1.156秒 解:4本の辺を削除 +−0−+−1−+−2−+ | | | 12 A B 14 C 15 | | | +−3−+−4−+ + | | | | 16 D 17 E 18 F 19 | | | | + +−7−+−8−+ | | | 20 G 21 H I 23 | | | +−9−+−10−+−11−+ 解:4本の辺を削除 +−0−+−1−+−2−+ | | | 12 A 13 B C 15 | | | + +−4−+−5−+ | | | | 16 D 17 E 18 F 19 | | | | +−6−+−7−+ + | | | 20 G H 22 I 23 | | | +−9−+−10−+−11−+
4本の辺を削除したとき,正方形はABCDEFGHIと真ん中のEの2つになる。
判りやすい図にすると以下のようになる。
プログラムのソースは以下の通り。
#include "puzutl.h" const ulong bit0 = 0x00000001; const ulong bit1 = 0x00000002; const ulong bit2 = 0x00000004; const ulong bit3 = 0x00000008; const ulong bit4 = 0x00000010; const ulong bit5 = 0x00000020; const ulong bit6 = 0x00000040; const ulong bit7 = 0x00000080; const ulong bit8 = 0x00000100; const ulong bit9 = 0x00000200; const ulong bit10 = 0x00000400; const ulong bit11 = 0x00000800; const ulong bit12 = 0x00001000; const ulong bit13 = 0x00002000; const ulong bit14 = 0x00004000; const ulong bit15 = 0x00008000; const ulong bit16 = 0x00010000; const ulong bit17 = 0x00020000; const ulong bit18 = 0x00040000; const ulong bit19 = 0x00080000; const ulong bit20 = 0x00100000; const ulong bit21 = 0x00200000; const ulong bit22 = 0x00400000; const ulong bit23 = 0x00800000; const ulong bit24 = 0x01000000; void print_rect( int r); int main( int argc, cstring argv[]) { // +−0−+−1−+−2−+ // | | | | // 12 A 13 B 14 C 15 // | | | | // +−3−+−4−+−5−+ // | | | | // 16 D 17 E 18 F 19 // | | | | // +−6−+−7−+−8−+ // | | | | // 20 G 21 H 22 I 23 // | | | | // +−9−+−10−+−11−+ ulong rect[14] = { // 正方形の定義 /*A*/ bit0|bit3|bit12|bit13, /*B*/ bit1|bit4|bit13|bit14, /*C*/ bit2|bit5|bit14|bit15, /*D*/ bit3|bit6|bit16|bit17, /*E*/ bit4|bit7|bit17|bit18, /*F*/ bit5|bit8|bit18|bit19, /*G*/ bit6|bit9|bit20|bit21, /*H*/ bit7|bit10|bit21|bit22, /*I*/ bit8|bit11|bit22|bit23, /*ABDE*/ bit0|bit1|bit6|bit7|bit12|bit16|bit14|bit18, /*BCEF*/ bit1|bit2|bit7|bit8|bit13|bit17|bit15|bit19, /*DEGH*/ bit3|bit4|bit9|bit10|bit16|bit20|bit18|bit22, /*EFHI*/ bit4|bit5|bit10|bit11|bit17|bit21|bit19|bit23, /*ABCDEFGHI*/ bit0|bit1|bit2|bit9|bit10|bit11|bit12|bit16|bit20|bit15|bit19|bit23, }; int rect_size[14] = { // 1辺を1としたときの正方形の大きさ 1,1,1,1,1,1,1,1,1,4,4,4,4,9 }; ProcTime pt; // 処理時間計測 int max_lines_count = 0, lines_count; set<int> find; for( int i=0; i<= 0xFFFFFF; i++) { // 全ての辺の組み合わせを調べる int num_rect = 0; // 14個中の正方形の数を勘定する int find_rect[3]; // 見つけた正方形を記録する。3個以上正方形が見つかっても題意に反するので記録しない for( int j=0; j< 14; j++) { // 14個の正方形を全て調べる if( (rect[j]&i) == rect[j]) { // 正方形が見つかった find_rect[num_rect] = j; // 正方形を記録する num_rect++; // 個数も記録する if( num_rect> 2) break; // 問題は2個の正方形なので3個以上の場合題意に反する。 } } if( num_rect == 2 && // 見つかった正方形の数が2個で rect_size[find_rect[0]] != rect_size[find_rect[1]]) { // 正方形の大きさが異なる場合だけが題意を満たす if( (lines_count=bitcount(i)) >= max_lines_count) { // 現在までの最大の辺数のものが見つかった if( lines_count > max_lines_count) find.clear(); // 今までの辺数より大きい場合今まで記録したものは削除する find.insert( i); max_lines_count = lines_count; // 辺の数の最大値は今後これになる } } } pt.end(); ps( "Find %d件, %g秒\n", find.size(), pt.sec()); set<int>::iterator ite; for( ite=find.begin(); ite != find.end(); ite++) { // 全ての結果を出力する int i = *ite; print_rect(i); // 結果表示 } return 0; } // 以下出力部分,判りづらく本質的でないのでmainより後ろに持ってきた。 void Plus( int r, int bit) // plus()にするとコンパイルエラーになるのでPlus { if( r & bit) ps( "+"); else ps( " "); } void horz( int r, int bit) { int b = 1; if( r & bit) { for( int i=0; i< 24; i++) { if( bit & b) { break; } b <<= 1; } ps( "−"); if( i < 10) ps( "%-.2s", "0123456789"+i*2); else ps( "%2d", i); ps( "−"); } else { ps( " "); } } void vert( int r, int bit) { int b = 1; if( r & bit) { for( int i=0; i< 24; i++) { if( bit & b) { break; } b <<= 1; } if( i < 10) ps( "%-.2s", "0123456789"+i*2); else ps( "%2d", i); } else { ps( " "); } } void abcd( cstring s) { ps( " "); ps( "%s", s); ps( " "); } void space( int r, int bit) { if( r & bit) ps( "|"); else ps( " "); ps( " "); } void print_rect( int r) { // +−0−+−1−+−2−+ // | | | | // 12 A 13 B 14 C 15 // | | | | // +−3−+−4−+−5−+ // | | | | // 16 D 17 E 18 F 19 // | | | | // +−6−+−7−+−8−+ // | | | | // 20 G 21 H 22 I 23 // | | | | // +−9−+−10−+−11−+ ps( "解:%d本の辺を削除\n", 24-bitcount(r)); // +−0−+−1−+−2−+ Plus(r,bit0|bit12); horz(r,bit0); Plus(r,bit0|bit1|bit13); horz(r,bit1); Plus(r,bit1|bit2|bit14); horz(r,bit2); Plus(r,bit2|bit15); ps( "\n"); // | | | | space(r,bit12); space(r,bit13); space(r,bit14); space(r,bit15); ps( "\n"); // 12 A 13 B 14 C 15 vert(r,bit12); abcd("A"); vert(r,bit13); abcd("B"); vert(r,bit14); abcd("C"); vert(r,bit15); ps( "\n"); // | | | | space(r,bit12); space(r,bit13); space(r,bit14); space(r,bit15); ps( "\n"); // +−3−+−4−+−5−+ Plus(r,bit12|bit3|bit16); horz(r,bit3); Plus(r,bit13|bit3|bit4|bit17); horz(r,bit4); Plus(r,bit14|bit4|bit5|bit18); horz(r,bit5); Plus(r,bit15|bit5|bit19); ps( "\n"); // | | | | space(r,bit16); space(r,bit17); space(r,bit18); space(r,bit19); ps( "\n"); // 16 D 17 E 18 F 19 vert(r,bit16); abcd("D"); vert(r,bit17); abcd("E"); vert(r,bit18); abcd("F"); vert(r,bit19); ps( "\n"); // | | | | space(r,bit16); space(r,bit17); space(r,bit18); space(r,bit19); ps( "\n"); // +−6−+−7−+−8−+ Plus(r,bit16|bit6|bit20); horz(r,bit6); Plus(r,bit17|bit6|bit7|bit21); horz(r,bit7); Plus(r,bit18|bit7|bit8|bit22); horz(r,bit8); Plus(r,bit19|bit8|bit23); ps( "\n"); // | | | | space(r,bit20); space(r,bit21); space(r,bit22); space(r,bit23); ps( "\n"); // 20 G 21 H 22 I 23 vert(r,bit20); abcd("G"); vert(r,bit21); abcd("H"); vert(r,bit22); abcd("I"); vert(r,bit23); ps( "\n"); // | | | | space(r,bit20); space(r,bit21); space(r,bit22); space(r,bit23); ps( "\n"); // +−9−+−10−+−11−+ Plus(r,bit20|bit9); horz(r,bit9); Plus(r,bit21|bit9|bit10); horz(r,bit10); Plus(r,bit22|bit10|bit11); horz(r,bit11); Plus(r,bit23|bit11); ps( "\n"); ps( "\n"); }