#include
#include
#include
using namespace std;
const int N = 100;
int amount = 0;
int board[N][N];
void IncompleteChessBoard();
void Cover(int tr, int tc, int dr, int dc, int sizes);//tr子棋盘左上角方格所在行
//tc子棋盘左上角方格所在列
//dr残缺方格行
//dc残缺方格列
//sizes棋盘的行数或者列数
void OutputBoard(int board[][N], int sizes);
int main ()
{
IncompleteChessBoard();
}
void IncompleteChessBoard()
{
int k = 2;//假设棋盘有2^k*2^k个方格
int sizes = 1, x, y, i, j;
sizes = pow(2, k);//棋盘的边长
x = 1, y = 3;//假定(1,3)位残缺位
Cover(0, 0, x, y, sizes);
OutputBoard(board, sizes);
}
void Cover(int tr, int tc, int dr, int dc, int sizes)
{
int s, t;
if(sizes < 2)
return;
amount++;
t = amount;//t中存储的是已经填充的拼图数
s = sizes / 2;//s是子棋盘边长的一半
if(dr < tr + s && dc < tc + s)//证明残缺位置在子棋盘的左上部分
{
Cover(tr, tc, dr, dc, s);//此时子棋盘的左上角方格坐标和残缺方格坐标不变 只需要将子棋盘的规模缩小即可
board[tr + s - 1][tc + s] = t;//这三步操作的目的是将子棋盘的中间位置进行覆盖 避开左上部分 因为已知残缺部分在左上
board[tr + s][tc + s - 1] = t;
board[tr + s][tc + s] = t;
//依次递归覆盖其他三个部分
Cover(tr, tc + s, tr + s - 1, tc + s, s);//右上部分 此时的残缺位置是刚刚在当前子棋盘中部覆盖的部分
Cover(tr + s, tc, tr + s, tc + s - 1, s);
Cover(tr + s, tc + s, tr + s, tc + s, s);
}
//下面几部分原理相同 都是讲子棋盘划分四块然后进行递归 并构造新的残缺
else if(dr < tr + s && dc >= tc + s)
{
Cover(tr, tc + s, dr, dc, s);
board[tr + s - 1][tc + s - 1] = t;
board[tr + s][tc + s - 1] = t;
board[tr + s][tc + s] = t;
Cover(tr, tc, tr + s - 1, tc + s - 1, s);
Cover(tr + s, tc, tr + s, tc + s - 1, s);
Cover(tr + s, tc + s, tr + s, tc + s, s);
}
else if(dr >= tr + s && dc < tc + s)
{
Cover(tr + s, tc , dr, dc, s);
board[tr + s - 1][tc + s - 1] = t;
board[tr + s - 1][tc + s] = t;
board[tr + s][tc + s] = t;
Cover(tr, tc, tr + s - 1, tc + s - 1, s);
Cover(tr, tc + s, tr + s - 1, tc + s, s);
Cover(tr + s, tc + s, tr + s, tc + s, s);
}
else if(dr >= tr + s && dc >= tc + s)
{
Cover(tr + s, tc + s, dr, dc, s);
board[tr + s - 1][tc + s - 1] = t;
board[tr + s - 1][tc + s] = t;
board[tr + s][tc + s - 1] = t;
Cover(tr, tc, tr + s - 1, tc + s - 1, s);
Cover(tr, tc + s, tr + s - 1, tc + s, s);
Cover(tr + s, tc, tr + s, tc + s - 1, s);
}
}
void OutputBoard(int board[][N], int sizes)
{
for(int i = 0; i < sizes; i++)
{//一次中填充的拼图(3块)有相同的编号
for(int j = 0; j < sizes; j++)
{
cout << board[i][j] << " ";
}
cout << endl;
}
}