棋盘覆盖

题意:有一个2^n*2^n的棋盘,在棋盘上面有一个特殊的方块,在此棋盘上面使用L型的骨牌进行覆盖,而且不能覆盖特殊的方块而且任意的骨牌也不能重叠,问应该怎么用L型的骨牌覆盖此棋盘?

棋盘:

棋盘覆盖_第1张图片

这是一个棋盘,红色的为特殊的方格,我们要用如下的四种L型骨牌覆盖此棋盘:

L型骨牌:

 棋盘覆盖_第2张图片

思路:使用分治法对棋盘进行覆盖,首先把棋盘划分成四个部分,那么特殊的方格一定位于四个小的棋盘中的某一个。分别对四个小的棋盘进行覆盖,由于分治法处理的是划分成相同的情况,而特殊的方格只有一个且位于某一个小的棋盘中,我们需要把另外的三个棋盘都拿一个方格来作为特殊的方格,由此想出把拿出的三个格子组成一个L型骨牌,这样就满足了每个小的棋盘都一个

特殊的方格,而且拿出来的特殊方格形成一个L型的骨牌。然后对四个小的棋盘分而治之,直到方格数为1就停止!表明已经到达了最小的问题了。

棋盘覆盖_第3张图片

a图是一个原始的棋盘,把大的棋盘划分成四个更小的棋盘,b图红色的代表原来的特殊的方格,而三个黄色的方格是没有特殊方格的棋盘拿出来的,在中间的位置刚好组成一个L型的骨牌。

代码:

#include 
#include 
#include
const int maxn = 500;
using namespace std;
int board[maxn][maxn],index = 0;//棋盘数组//指示L型棋盘的索引 
//参数解析:
//tr(棋盘左上角方格的行号),tc(棋盘左上角方格的列号),dr(特殊方格的行号),dc(特殊方格的列号),size(棋盘大小) 
void chessBoard(int tr,int tc,int dr,int dc,int size){
	if(size == 1){//只有一个方格了,最小问题,直接返回 
		return; 
	} 
	int t = ++index,s = size/2;
	
	if(dr=tc+s){//特殊的方块在右上角的区域 
		chessBoard(tr,tc+s,dr,dc,s);
	}else{
		board[tr+s-1][tc+s] = t;
		chessBoard(tr,tc+s,tr+s-1,tc+s,s);
	} 
	if(dr>=tr+s && dc=tr+s && dc>=tc+s){//特殊方块右下角 
		chessBoard(tr+s,tc+s,dr,dc,s);
	}else{
		board[tr+s][tc+s] = t;
		chessBoard(tr+s,tc+s,tr+s,tc+s,s);
	} 
}
void print(int n){
	for(int i=0;i

 

 

 

你可能感兴趣的:(算法类)