棋盘覆盖问题
1、问题描述
在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
2、解决思路
这道题可以用递归与分治的思想来解决,也就是把一个大的棋盘分成4个小棋盘,检索填充,然后在把小棋盘继续细分,直到棋盘中只包含一个格子为止。
3、核心代码
/** * 棋盘覆盖函数 * @param tr:表示当前所在棋盘的左上角的行位置 * @param tc:表示当前所在棋盘的左上角的列位置 * @param dr:表示特殊棋盘的行位置 * @param dc:表示特殊体盘的列位置 * @param size:棋盘的长度 */
public static void chessBoard(int tr,int tc,int dr,int dc,int size) {
//如果当前棋盘只有一个方格时,返回函数
if(size == 1) {
return;
}
int curPattern = ++count;
//将棋盘从中间分为4部分
size = size>>1;
//左上部分
if(dr<tr+size && dc<tc+size) {
//如果左上部分包含特殊棋盘,直接递归找左上部分
chessBoard(tr,tc,dr,dc,size);
}else {
//如果不在左上部分,则先将左上部分的右下角自定义成一个特殊棋盘,然后再递归
matrix[tr+size-1][tc+size-1] = curPattern;
chessBoard(tr,tc,tr+size-1,tc+size-1,size);
}
//右上部分
if(dr<tr+size && dc>=tc+size) {
//如果右上部分包含特殊棋盘,直接递归找右上部分
chessBoard(tr,tc+size,dr,dc,size);
}else {
//如果不在右上部分,则先将右上部分的左下角自定义成一个特殊棋盘,然后再递归
matrix[tr+size-1][tc+size] = curPattern;
chessBoard(tr,tc+size,tr+size-1,tc+size,size);
}
//左下部分
if(dr>=tr+size && dc<tc+size) {
//如果左下部分包含特殊棋盘,直接递归找左下部分
chessBoard(tr+size,tc,dr,dc,size);
}else {
//如果不在左下部分,则先将左下部分的右上角自定义成一个特殊棋盘,然后再递归
matrix[tr+size][tc+size-1] = curPattern;
chessBoard(tr+size,tc,tr+size,tc+size-1,size);
}
//右下部分
if(dr>=tr+size && dc>=tc+size) {
//如果右下部分包含特殊棋盘,直接递归找右下部分
chessBoard(tr+size,tc+size,dr,dc,size);
}else {
//如果不在右下部分,则先将右下部分的左上角自定义成一个特殊棋盘,然后再递归
matrix[tr+size][tc+size] = curPattern;
chessBoard(tr+size,tc+size,tr+size,tc+size,size);
}
}