棋盘覆盖问题-分治法

什么是棋盘覆盖方法?

    我去找其他人的解释,恰恰发现一个矛盾的地方,就是看解释比较难理解,但是看解决棋盘覆盖的过程,就很容易理解什么是棋盘覆盖问题了。所以这里就不解释了,直接给一个解决16*16的棋盘解决过程,看完过程,相信你也理解了什么是棋盘问题了。

    如下:

首先给出一个包含一个奇异点的16*16棋盘:


第一步是将该棋盘分为四个等大的子棋盘:


然后将该棋盘看做是4*4的棋盘,可以看到奇异点在左上角的子棋盘中,那么这一步的任务就是用一个(真的是一个)L型的棋子(下图中红色的格子)将其他三个子棋盘构造成含奇异点的子棋盘:


下一步是将红线分割的子棋盘又切割成四个子棋盘(白色线切开的子棋盘):


然后对每个红色线包围在里面的子棋盘,用一个L型棋子(黄色)又构造出奇异点,使得每个子棋盘都有一个奇异点,即白色线围起来的格子看做是一个整体,里面包含一个黄色的奇异点:



下一步是继续讲白色线包围的格子切分为4个子棋盘,这里为了方便观察,将前面所有的分割线去掉:



同理,对黄色的棋盘构造含奇异点的子棋盘(蓝色):


最后可以分割到2*2的格子,然后每个2*2的子棋盘都已经包含一个奇异点了,剩下的就是用L型旗子去填好剩下的三个格子。

好了,任务完成。是不是觉得很简单呢,觉得简单的话就点个赞呗。


具体的实现代码,请参考我的另外博客。棋盘覆盖-分治法(代码实现)

  • 193
    点赞
  • 280
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
二级残缺棋盘覆盖问题是指在一个大小为2^n x 2^n的棋盘中,去掉其中一个格子后,如何使用L型骨牌(一种覆盖三个方格的L形图案)将剩下的格子完全覆盖,且每个L型骨牌不重叠、不遗漏地覆盖棋盘中的三个方格。 该问题可以使用分治算法解决。具体思路为: 1. 对于当前的残缺棋盘,找到其中任意一个空白格子,并以该空白格子为中心,将整个棋盘分成四个大小相等的子棋盘,其中包含三个L型骨牌覆盖的方案。 2. 在上述四个子棋盘中,选取其中一个仍然是残缺的子棋盘,重复步骤1,直到所有的空白格子都被L型骨牌覆盖。 以下是C语言的分治算法代码实现,其中board数组代表棋盘,size表示当前棋盘大小,x和y表示当前空白格子的坐标。 ``` #include <stdio.h> #define MAXN 1024 int board[MAXN][MAXN]; int cnt = 0; void chessboard(int tr, int tc, int dr, int dc, int size, int x, int y) { if (size == 1) return; // 递归结束条件 int t = ++cnt; int s = size / 2; // 当前空白格子在左上角子棋盘中 if (x < tr + s && y < tc + s) { chessboard(tr, tc, tr + s - 1, tc + s - 1, s, x, y); } else { board[tr + s - 1][tc + s - 1] = t; // 其他三个子棋盘 chessboard(tr, tc, tr + s - 1, tc + s - 1, s, tr + s - 1, tc + s - 1); chessboard(tr, tc + s, tr + s - 1, tc + s, s, tr + s - 1, tc + s); chessboard(tr + s, tc, tr + s, tc + s - 1, s, tr + s, tc + s - 1); chessboard(tr + s, tc + s, dr, dc, s, tr + s, tc + s); } } int main() { int n = 8; // 棋盘大小为2^n x 2^n int x = 6; // 空白格子坐标 int y = 5; board[x][y] = -1; chessboard(0, 0, n-1, n-1, n, x, y); // 分治算法 for (int i=0; i<n; i++) { for (int j=0; j<n; j++) { printf("%3d", board[i][j]); } printf("\n"); } return 0; } ```
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值