问题描述:
棋盘覆盖问题要求在2^k * 2^k 个方格组成的棋盘中,你给定任意一个特殊点,用一种方案实现对除该特殊点的棋盘实现全覆盖。
模型如下:
四种不同形状的骨牌
方盘
解决方法:
如何通过分治来解决问题?
首先我们将一个2^k * 2^k 方盘划分为四个2^(k-1) * 2^(k-1)的方盘,进而将一个大方盘的问题转移到小方盘上,依次递归进而将问题转移到1*1的方盘上来。
对于特殊方格和已经放上骨牌的方格我们会将其忽略
在小方盘中我们会首先对没有特殊方格的方盘的角落进行处理,如下
#include <iostream>
using namespace std;
int tile = 1;//全局变量 骨牌编号
int Board[8][8];//棋盘
void ChessBoard(int tr,int tc,int dr,int dc,int size);
int main()
{
for(int i=0; i<8; i++)
{
for(int j=0; j<8; j++)
{
Board[i][j] = 0;
}
}
ChessBoard(0,0,2,3,8);
for(int i=0; i<8; i++)
{
for(int j=0; j<8; j++)
{
cout<<Board[i][j]<<"\t";
}
cout<<endl;
}
}
/**
* tr : 棋盘左上角的行号,tc棋盘左上角的列号
* dr : 特殊方格左上角的行号,dc特殊方格左上角的列号
* size :size = 2^k 棋盘规格为2^k*2^k
*/
void ChessBoard(int tr,int tc,int dr,int dc,int size)
{
if(size == 1)
{
return;
}
int t = tile++;//L型骨牌编号
int s = size/2;//分割棋盘
//覆盖左上角子棋盘
if(dr<tr+s && dc<tc+s)//特殊方格在此棋盘中
{
ChessBoard(tr,tc,dr,dc,s);
}
else//特殊方格不在此棋盘中
{
//用编号为t的骨牌覆盖右下角
Board[tr+s-1][tc+s-1] = t;
//覆盖其余方格
ChessBoard(tr,tc,tr+s-1,tc+s-1,s);
}
//覆盖右上角子棋盘
if(dr<tr+s && dc>=tc+s)//特殊方格在此棋盘中
{
ChessBoard(tr,tc+s,dr,dc,s);
}
else//特殊方格不在此棋盘中
{
//用编号为t的骨牌覆盖左下角
Board[tr+s-1][tc+s] = t;
//覆盖其余方格
ChessBoard(tr,tc+s,tr+s-1,tc+s,s);
}
//覆盖左下角子棋盘
if(dr>=tr+s && dc<tc+s)//特殊方格在此棋盘中
{
ChessBoard(tr+s,tc,dr,dc,s);
}
else//特殊方格不在此棋盘中
{
//用编号为t的骨牌覆盖右上角
Board[tr+s][tc+s-1] = t;
//覆盖其余方格
ChessBoard(tr+s,tc,tr+s,tc+s-1,s);
}
//覆盖右下角子棋盘
if(dr>=tr+s && dc>=tc+s)//特殊方格在此棋盘中
{
ChessBoard(tr+s,tc+s,dr,dc,s);
}
else//特殊方格不在此棋盘中
{
//用编号为t的骨牌覆盖左上角
Board[tr+s][tc+s] = t;
//覆盖其余方格
ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
}
}