问题描述
在一个
个方格组成的棋盘中,有一个方格称为特殊方格。 使用以下四种L型骨牌覆盖棋盘上除特殊方格外的所有方格,且不能重叠。
解题
首先考虑 的情形:
答案明显,非常清晰
再考虑 情形:
将整个棋盘分成4格部分。
有特殊方格的那个部分,容易解决;
没有特殊方格的其他三个子棋盘,可以通过加入一个横跨三个子棋盘的骨牌,将问题转化为 规模。
这样推广到 情形即可。
struct ChessBoard {int x, y, size};
strcut Cell {int x, y};
void Cover(ChessBoard b, Cell c) {
// 基准情形
if (b.size == 2) {
// 输出结果
return;
}
// 需要划分的情形
int midX = b.x + size >> 1;
int midY = b.y + size >> 1;
int quadrant = 0; // 标记特殊方格位于第几象限
if (c.x < midX) {
if (c.y < midY) {
// 判断象限,求解包含特殊方格的子棋盘的子问题
quadrant = 3;
Cover({b.x, b.y. size >> 1}, c);
// 放置一个相应形状的L形骨牌在中间
}
else {
quadrant = 2;
Cover({b.x, midY, size >> 1}, c);
// ...
}
}
else {
if (c.y < midY) {
quadrant = 4;
...
}
else {
quadrant = 1;
...
}
}
// 求解没有特殊方格的剩余3格子棋盘的子问题
if (quadrant != 1)
Cover({midX, midY, size >> 1}, {midX, midY});
if (quadrant != 2)
Cover({b.x, midY, size >> 1}, {midX - 1, midY});
if (quadrant != 3)
Cover({b.x, b.y, size >> 1}, {midX - 1, midY - 1});
if (quadrant != 4)
Cover({midX, b.y, size >> 1}, {midX, midY - 1});
}