前言
简单问题,写的不好,大佬见谅.
如有疏漏,恳请指正,小编垂首.
问题描述:
有一个
2
k
∗
2
k
2^k*2^k
2k∗2k的棋盘,有一个方格与其他不同,现要用L型骨牌覆盖出特殊放个以外的所有棋盘,骨牌可以任意旋转,求覆盖方法.
问题解析:
棋盘大小为
2
k
∗
2
k
2^k*2^k
2k∗2k
可划分为4个象限,采用分治法求解
实现代码:
代码如下(示例):
#include<cstdio>
using namespace std;
int k;
int x, y;
int board[1024][1024];
int tile = 1;
//通过左上角元素的下标确定区间
void ChessBoard(int tr,int tc,int dr,int dc,int size) {
if (size == 1) return;
int t = tile++;
int s = size / 2;//分区间
//左上
if (dr < tr + s && dc < tc + s) {
ChessBoard(tr, tc, dr, dc, s);
}
else {
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+s, tc, dr, dc, s);
}
else {
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, 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 >= tc + s) {
ChessBoard(tr, tc, dr, dc, s);
}
else {
board[tr + s][tc + s] = t;//覆盖左上角
ChessBoard(tr+s, tc+s, tr + s, tc + s, s);//左上角作为特殊格继续处理该象限
}
}
int main() {
k = 3;
x = 1;y = 2;//特殊格坐标
int size = 1 << k;
ChessBoard(0, 0, x, y, size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%4d", board[i][j]);
}
printf("\n");
}
}
注意事项
对象限递归求解,不要搞错坐标哦