该篇虽然与很多的博客、解说一样讲的都是棋盘覆盖的解法。但是,该篇更多地倾向于“证明”,这也是我与很多读者都想知道的,而不是开篇就上代码。
目录
0,问题描述
1,相关博客
http://blog.csdn.net/akof1314/article/details/5423608
http://www.cnblogs.com/lsxqw2004/archive/2008/10/16/1313086.html
http://blog.csdn.net/onlyonename/article/details/7524525
2,提出命题
k=n(k∈N+)且棋盘中只有一个特殊方块时,一定可以用相应的L型骨牌将棋盘覆盖。
3,命题证明
数学归纳法
(1) 当k=1时,棋盘大小为2*2,无论特殊方块在哪个格,都有相应的L型骨牌可覆盖棋盘。即当k=1时命题成立
(2) 假设:当k=n(k∈N+)时,可用相应的L型骨牌完全覆盖。则当k=n+1时,棋盘可分为4块2k*2k的棋盘,令棋盘中间的小方块为特殊方块,则由上述假设k=n时可知,另外3块2k*2k也可以用相应的L型骨牌覆盖。
综上,k=n(k∈N+)且棋盘中只有一个特殊方块时,一定可以用相应的L型骨牌将棋盘覆盖。
4,分析算法
① 将2k*2k的棋盘拆分成4个2k-1*2k-1
② 将包含特殊方块的棋盘进行分块处理。
③ 将不包含特殊方块的棋盘的靠近中间部分的小方块假设为特殊的小方块。
④ 当k=1时退出递归
5,代码实现
package divideAndConquer;
/**
* @Input包含一个不同方格的棋盘
* @Output已用4种不同形态的L型骨牌覆盖的棋盘
*/
public class ChessBoard {
/**
* 第count块L型骨牌
*/
public static int count = 0;
public static void main(String[] args) {
int k = 3;
int dr = 2, dc = 2;// 方块坐标
int SIZE = 1 <<k;
int[][] chesses = new int[SIZE][SIZE];
chesses[dr][dc] = -1;
System.out.println("覆盖前:");
sop(chesses);
chessBoard(chesses, 0, 0, dr, dc, SIZE);
System.out.println("覆盖后:");
sop(chesses);
}
/**
* 棋盘覆盖
* @param chesses 棋盘
* @param sr 棋盘的左上角对应的行数
* @param sc 棋盘的左上角对应的列数
* @param dr 特殊方块对应的行数
* @param dc 特殊方块对应的行数
* @param SIZE 棋盘宽度
*/
public static void chessBoard(int[][] chesses, int sr, int sc, int dr,
int dc, int SIZE) {
if (SIZE == 1)
return;
int newSize = SIZE / 2;
int newCount = count;
count++;
/*
* 左上角棋盘
*/
if (sr <= dr && dr < sr + newSize && sc <= dc && dc < sc + newSize) {
chessBoard(chesses, sr, sc, dr, dc, newSize);
} else {
chesses[sr + newSize - 1][sc + newSize - 1] = newCount;
chessBoard(chesses, sr, sc, sr + newSize - 1, sc + newSize - 1,
newSize);
}
/*
* 右上角棋盘
*/
if (sr <= dr && dr < sr + newSize && sc + newSize <= dc) {
chessBoard(chesses, sr, sc + newSize, dr, dc, newSize);
} else {
chesses[sr + newSize - 1][sc + newSize] = newCount;
chessBoard(chesses, sr, sc + newSize, sr + newSize - 1, sc
+ newSize, newSize);
}
/*
* 左下角棋盘
*/
if (sr + newSize <= dr && sc <= dc && dc < sc + newSize) {
chessBoard(chesses, sr + newSize, sc, dr, dc, newSize);
} else {
chesses[sr + newSize][sc + newSize - 1] = newCount;
chessBoard(chesses, sr + newSize, sc, sr + newSize, sc + newSize
- 1, newSize);
}
/*
* 右下角棋盘
*/
if (sr + newSize <= dr && sc + newSize <= dc) {
chessBoard(chesses, sr + newSize, sc + newSize, dr, dc, newSize);
} else {
chesses[sr + newSize][sc + newSize] = newCount;
chessBoard(chesses, sr + newSize, sc + newSize, sr + newSize, sc
+ newSize, newSize);
}
}
/**
* 显示
*/
public static void sop(int[][] nums) {
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums[i].length; j++) {
System.out.printf(" %4d", nums[i][j]);
}
System.out.println();
}
System.out.println("---------------------------------");
}
}