棋盘覆盖分析与实现

一、什么是棋盘覆盖?

在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其他方格不同,则称该方格为一个特殊方格,且称该棋盘为一个特殊棋盘。显然,特殊方格在棋盘上出现的位置有 4^k 种情况,即k>=0,有4^k种不同的特殊棋盘。

棋盘覆盖:用4种不同形态的L型骨牌覆盖一个给定的特殊棋盘(即特殊方格的位置已经确定了)上除特殊方格外的所有方格,且任何两个L型骨牌不得重复覆盖。按照规则,我们很容易知道,在2^k*2^k的棋盘覆盖中,用到的L型骨盘数恰为(4^k-1)/3,即(所有方格个数-特殊方格个数)/3。

如下图,为k=2时的一个特殊棋盘(相同颜色的三个小方格组成一个L型骨牌)和4种不同形态的L型骨牌,蓝色的为特殊方格:


                                                                             k=2时的一个特殊棋盘

二、实现棋盘覆盖的思路和方法

棋盘覆盖实现的基本方法为分治法,是设计棋盘覆盖的一个简捷的算法,那什么是分治法?

分治法的基本思路:将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。递归地解决这些子问题,然后将各个子问题的解合并得到原问题的解。简单地说,就是将规模为n的问题自顶向下分解,直到子问题分解到足够小,可以容易解决时,再自底向上合并,从而得到原来的解。

分析思路:当k>0时,将2^k*2^k棋盘分割为4个2^(k-1)*2^(k-1)子棋盘,如图所示:

特殊方格必定位于这四个小棋盘中,其余三个子棋盘没有特殊方格,为了将这三个无特殊方格的子棋盘转换为特殊棋盘,我们可以用一个L型骨盘覆盖这三个较小棋盘的会合处,如图所示:

从图上可以看出,这三个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将问题分解为4个较小规模的棋盘覆盖问题。递归地使用这种分割方法,直至棋盘简化为1*1棋盘,就结束递归。

实现这种算法的分析:每次都对分割后的四个小方块进行判断,判断特殊方格是否在里面。这里的判断的方法是每次先记录下整个大方块的左上角方格的行列坐标,然后再与特殊方格坐标进行比较,就可以知道特殊方格是否在该块中。如果特殊方块在里面,这直接递归下去求即可,如果不在,这根据分割的四个方块的不同位置,把右下角、左下角、右上角或者左上角的方格标记为特殊方块,然后继续递归。在递归函数里,还要有一个变量s来记录边的方格数,每次对方块进行划分时,边的方格数都会减半,这个变量是为了方便判断特殊方格的位置。

三、棋盘覆盖的具体实现代码

#include <stdio.h>
#include <stdlib.h>int num = 0;
int Matrix[100][100];
void chessBoard(int tr, int tc, int dr, int dc, int size);
int main()
{int size,r,c,row,col;printf("请输入棋盘的行列号");scanf("%d",&size);printf("请输入特殊方格的行列号");scanf("%d %d",&row,&col);chessBoard(0,0,row,col,size);for (r = 0; r < size; r++){for (c = 0; c < size; c++){printf("%2d ",Matrix[r][c]);}printf("\n");}return 0;
}void chessBoard(int tr, int tc, int dr, int dc, int size)
{if (size==1) return;int s = size/2;     //分割棋盘int t = ++num;      //L型骨牌号//覆盖左上角子棋盘if (dr < tr + s && dc < tc +s)                {//特殊方格在此棋盘中chessBoard(tr,tc,dr,dc,s);}else            //此棋盘中无特殊方格{//用t号L型骨牌覆盖右下角Matrix[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,tc+s,dr,dc,s);}else            //此棋盘中无特殊方格{//用t号L型骨牌覆盖左下角Matrix[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+s,tc,dr,dc,s);}else{//用t号L型骨牌覆盖右上角Matrix[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+s,tc+s,dr,dc,s);}else{//用t号L型骨牌覆盖左上角Matrix[tr+s][tc+s] = t;//覆盖其余方格chessBoard(tr+s,tc+s,tr+s,tc+s,s);}}

运行结果如下图:

上述算法中用一个二维整型数组 Matrix 表示棋盘,Matrix[0][0]是棋盘的左上角方格。num 是一个全局整型变量,用来表示 L 型骨牌的编号,其初始值为1。算法的输入参数是:

tr 棋盘左上角方格的行号
tc 棋盘左上角方格的列号
dr 特殊方格的行号
dc 特殊方格的列号
size size=2^k,棋盘规格为 2^k * 2^k

Reference:
1、https://www.cnblogs.com/crx234/p/5988055.html
2、计算机算法设计与分析王晓东第五版。(如果需要对应课后习题答案的话可以评论区留言,我会发链接哒)

【算法】棋盘覆盖详解,基础教程~相关推荐

  1. 【算法知识】详解希尔排序算法

    前言 已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 当待插入元素是一个很小(当需求是从小到大排序时,从大到小排序时此处为很大)直接插入排序需要移动 ...

  2. 【算法知识】详解直接插入排序算法

    前言 已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 在玩扑克牌的时候,我们抽到一张牌的时候,都是将它插入到当前手中牌的合适位置的. 如下图: (上图来自算法导论) 直接插入排序 ...

  3. 抖音推荐算法原理全文详解

    阅读目录 一.系统概览 二.内容分析 三.用户标签 四.评估分析 五.内容安全 抖音推荐算法原理全文详解 本次分享将主要介绍今日头条推荐系统概览以及内容分析.用户标签.评估分析,内容安全等原理. 回到 ...

  4. 【算法知识】详解堆排序算法

    点击蓝色字关注我们! 什么是堆 「堆」首先是一个完全二叉树,「堆」分为「大顶堆」和「小顶堆」: 「大顶堆」 : 每个节点的值大于或等于其左右孩子节点的值,称为大顶堆. 「小顶堆」同理就是每个节点的值小 ...

  5. 【算法知识】详解基数排序算法

    已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 [算法知识]详解归并排序算法 基本思想 基数排序的思想是将整数按位数切 ...

  6. 【算法知识】详解归并排序算法

    已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 基本思想 归并排序的基本思想是: 先将序列一次次分成子序列,直到子序列 ...

  7. 【算法知识】详解快速排序算法

    基本思想 已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 本文的思路是以从小到大为例讲的. 快速排序的基本思想是任取待排序序列的一个元素作为中心元素 ...

  8. linux sed p变量,Linux sed 命令详解系列教程之各种问题解决

    本文目录: 1 sed中使用变量和变量替换的问题 2 反向引用失效问题 3 "-i"选项的文件保存问题 4 贪婪匹配问题 5 sed命令"a"和"N& ...

  9. 试设计递归算法dfs traverse_BFS 算法框架套路详解

    作者:labuladong 公众号:labuladong 后台有很多人问起 BFS 和 DFS 的框架,今天就来说说吧. 首先,你要说 labuladong 没写过 BFS 框架,这话没错,今天写个框 ...

最新文章

  1. python免费自学爬虫_这套Python爬虫学习教程,不到一天即可新手到进阶!免费领...
  2. mnist学习实例(2)
  3. 基于ECS部署LAMP环境实验记录
  4. 【鸿蒙 HarmonyOS】UI 布局 ( 网格布局 TableLayout )
  5. 直播 | 复旦大学许燚:少量标注样本场景下基于数据编程的半监督分类
  6. 1.非关系型数据库(Nosql)之mongodb:mongodb的安装,环境变量配置,数据库服务端启动,客户端启动
  7. NIO与传统IO的区别(形象比喻)
  8. 深度学习算法简要综述(上)
  9. 十八般武艺玩转GaussDB(DWS)性能调优:SQL改写
  10. Discuz 7.2 /faq.php SQL注入漏洞
  11. LeetCode 688. “马”在棋盘上的概率
  12. 视频帧AI分析后编码
  13. 除了微软默认的ppt服务器外,微软如此解释这一新政。据了解,除了MSN与Skype有很多类似功能之外.ppt...
  14. python numpy官方文档_[ Numpy中文文档 ] 介绍 - pytorch中文网
  15. 朋友圈加粗字体数字_如何让你的朋友圈骚到脱颖而出?
  16. 怎么用dw修改PHP网页模板,DW基础篇:如何使用DW运用网页模板
  17. 重装电脑系统完整教程
  18. 【python】耗时统计小程序
  19. MarkdownPad 2使用教程
  20. 【论文阅读】深度强化学习的攻防与安全性分析综述

热门文章

  1. 什么是 gc root
  2. intellij最常用的快捷键和快速输入技巧
  3. 浅谈前端三大框架和vue2、vue3的选择
  4. 常见的运行时异常有哪些?
  5. kafka集群的部署
  6. 映射网络驱动盘开机不需输入密码
  7. mingw+cmake编译Assimp库遇到undefine问题
  8. 最近发现新版的chrome://flags没有另存为 mhtml
  9. 解放号使能软件产业 贡献数字中国!
  10. Windows超级管理器#这可能是东半球最具颜值的系统管理工具