在一个2k × 2k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的棋盘上除特殊方格以外的所有方格,L型骨牌不能旋转,且任何两个L型骨牌不得重叠覆盖。
棋盘和标记为红色的特殊方格 4种L型骨牌
可以用分治法解决
当方阵的阶=1时 直接返回
当方阵的阶>1时 每次除2,分为四个小方阵。判断四个小方阵,若此方阵为普通方阵,将此方阵转换为特殊方阵。递归。
两种填法
1:当左上角方阵有特殊方块时,填此方阵右下角为特殊方块
当右上角方阵有特殊方块时,填此方阵左下角角为特殊方块
当左下角方阵有特殊方块时,填此方阵右上角为特殊方块
当右下角方阵有特殊方块时,填此方阵左上角为特殊方块
2:当左上角方阵有特殊方块时,填此方阵右下角相邻方阵边缘为特殊方块
* | |
* | * |
当右上角方阵有特殊方块时,填此方阵左下角相邻方阵边缘为特殊方块
* | |
* | * |
当左下角方阵有特殊方块时,填此方阵右上角相邻方阵边缘为特殊方块
* | * |
* |
当右下角方阵有特殊方块时,填此方阵左上角相邻方阵边缘为特殊方块
* | * |
* |
代码
#include <stdio.h>
int m[2<<8+1][2<<8+1];
int cnt;
/**
tr 特殊方块的横坐标
tc 特殊方块的纵坐标
dr 棋盘的左上角横坐标
dc 棋盘的左上角纵坐标
_size 棋盘的规格
cnt 计数
**/
void chessboard( int tr, int tc, int dr, int dc, int _size)
{
if( _size == 1 )
return;
int s = _size / 2;
int c = cnt++;
///左上角
if( tr < dr + s && tc < dc + s )
{
m[dr+s-1][dc+s] = 1; ///填骨型/如果此方阵为特殊方阵,填此方阵右下角相邻方阵边缘为特殊方块
m[dr+s][dc+s-1] = 1;
m[dr+s][dc+s] = 1;
chessboard( tr , tc, dr, dc, s);
}
else
{
/// m[dr+s-1][dc+s-1] = c; //填编号/如果此方阵为普通方阵,右下角填为特殊方块
chessboard( dr+s-1, dc+s-1 , dr, dc, s);
}
///右上角
if( tr < dr + s && tc >= dc + s )
{
m[dr+s-1][dc+s-1] = 2;
m[dr+s][dc+s-1] = 2;
m[dr+s][dc+s] = 2;
chessboard( tr, tc, dr, dc+s, s );
}
else
{
/// m[dr+s-1][dc+s] = c;
chessboard( dr+s-1, dc+s , dr, dc+s, s);
}
///左下角
if( tr >= dr + s && tc < dc + s )
{
m[dr+s-1][dc+s-1] = 3;
m[dr+s-1][dc+s] = 3;
m[dr+s][dc+s] = 3;
chessboard( tr, tc, dr+s, dc, s );
}
else
{
/// m[dr+s][dc+s-1] = c;
chessboard( dr+s, dc+s-1 , dr+s, dc, s);
}
///右下角
if( tr >= dr + s && tc >= dc + s )
{
m[dr+s-1][dc+s-1] = 4;
m[dr+s][dc+s-1] = 4;
m[dr+s-1][dc+s] = 4;
chessboard( tr, tc, dr+s, dc+s, s );
}
else
{
/// m[dr+s][dc+s] = c;
chessboard( dr+s, dc+s , dr+s, dc+s, s);
}
}
int main()
{
int t;
int k,x,y;
scanf("%d", &t);
while(t--)
{
cnt = 0;
scanf("%d%d%d",&k,&x,&y);
int c = 1<<k;
for( int i = 0; i < c; i++ )
{
for( int j = 0; j < c; j++)
m[i][j] = -1;
}
m[x-1][y-1] = 0;
chessboard(x-1,y-1,0,0,c);
/** //按编号输出
for( int i = 0; i < c; i++ )
{
for( int j = 0; j < c; j++ )
{
printf("%d",m[i][j]);
}
printf("\n");
}
**/
///按骨型输出
for( int i = 0; i < c; i++ )
{
for( int j = 0; j < c; j++ )
{
if( m[i][j] == 1 )
printf("d");
else if( m[i][j] == 2 )
printf("c");
else if( m[i][j] == 3 )
printf("b");
else if( m[i][j] == 4 )
printf("a");
else
printf("*");
}
printf("\n");
}
}
return 0;
}