分治法解决棋盘覆盖问题

问题描述:

在一个2k×2k(k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。显然,特殊方格在棋盘中出现的位置有4k中情形,因而有4k中不同的棋盘。棋盘覆盖问题要求用下图所示的4中不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何两个L型骨牌不得重复覆盖

算法设计:

使用分治策略。在一个2k *2k的棋盘中,当k大于0时,可以将棋盘分割成4个2k-1*2k-1子棋盘。如图所示:

特殊的方格位于4个较小的棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘化为特殊棋盘,可以用一个L型骨牌覆盖这三个较小棋盘汇合处,这三个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原来的问题简化成了4个更小规模的棋盘覆盖问题。递归的使用这种分割,直至棋盘简化为1*1的棋盘。

代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define MAX 32767
void initChess(int size);
void ChessBoard(int tr,int tc,int dr,int dc,int size);
void printChess(int size);
bool isLog2(int n);
int **Board;//棋盘,用于记录覆盖的顺序
int tile=1;//标记第几次覆盖 int main(){int size;printf("请输入棋盘的大小,棋盘大小应为2^k(k>0)\n"); scanf("%d",&size);//判断是否规模超过限制 if(size>MAX){printf("问题规模过大!"); }else if(isLog2(size)) {//判断规模是否为2的k次方 initChess(size);ChessBoard(0,0,0,(size/2)-1,size);printChess(size);return 0;}else{printf("请输入2^k的数(k>0)!\n"); }} void printChess(int size){printf("棋盘覆盖顺序如下:\n\n");for(int i=0;i<size;i++){for(int j=0;j<size;j++){printf("%d\t",Board[i][j]);}printf("\n\n");}
} void initChess(int size){Board=(int **)malloc(size*sizeof(int *));for(int i=0;i<size;i++){Board[i]=(int *)malloc(size*sizeof(int));}for(int x=0;x<size;x++){for(int y=0;y<size;y++){Board[x][y]=0;}}
}
//用于判断是否为2的k次方
bool isLog2(int n){if(n<0){return false;} double result=log(n)/log(2);if(result-(int)result==0){return true;}return false;
}//tr:棋盘左上角方格行号
//td:棋盘左上角方格列号
//dr:棋盘特殊方格行号
//dt:棋盘特殊方格列号
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,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+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+s,tc+s,dr,dc,s);}else{Board[tr+s][tc+s]=t;ChessBoard(tr+s,tc+s,tr+s,tc+s,s);}}

运行结果:

时间复杂度分析:


解递归方程的时间复杂度为:O(n)=O(4k)。

分治法解决棋盘覆盖问题相关推荐

  1. 【分治法】棋盘覆盖问题java实现

    文章目录 问题描述 问题分析 算法设计 java代码 问题描述 在一个2k × 2k个放个中,恰好只有一个方格是残缺的.也就是在这个棋盘中有一个方格与其它的格子不同, 我们称这种棋盘为残缺棋盘. 下图 ...

  2. 「分治法」棋盘覆盖问题

    一.问题描述 在一个2k×2 k(k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格. 棋盘覆盖问题要求用图所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格, ...

  3. 分治法解决最大子数组问题

    分治法解决最大子数组问题 参考文章: (1)分治法解决最大子数组问题 (2)https://www.cnblogs.com/Christal-R/p/Christal_R.html (3)https: ...

  4. 分治法解决组合总和问题(leetcode216)

    nums数组中元素是正整数 大问题转换为小问题 思路和分治法解决组合相同,代码也相似 分治法解决组合问题(递归)_m0_52043808的博客-CSDN博客 只不过递归出口时需要判断组合总和是否为n ...

  5. 分治法解决循环赛日程表

    分治法解决循环赛日程表 问题描述 设有n=2^k个运动员要进行羽毛球循环赛,现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次. (2)每个选手一天只能比赛一次. ( ...

  6. 分治法解决矩阵乘法问题

    分治法解决矩阵乘法问题 传统for循环: #include<iostream> #include<cstdio> #include <vector> #includ ...

  7. 分治法解决最小套圈问题

    /*     Copyright    by ZhongMing-Bian     Jan,6,2010   */ /*             分治法解决最小套圈问题                 ...

  8. 分治法解决最近点对问题

    问题 给定平面上n个点,找其中的一对点,使得在n个点的所有点对中,该点对的距离最小.严格地说,最接近点对可能多于1对.为了简单起见,这里只限于找其中的一对. 原理(这段为抄袭https://blog. ...

  9. 分治法解决计算凸包问题

    清华大学的邓俊辉老师的<计算几何>公开课中,在计算凸包问题时会遇到极点法和极边法: 极点法是假设所有的点都是凸包上的点,然后根据In-triangle测试,把去除不是极点的点,时间复杂度是 ...

最新文章

  1. 接口与抽象类的使用选择
  2. linux项目课程设计,LINUX课程设计项目需求解析.doc
  3. 使用nodejs代码在SAP C4C里创建Individual customer
  4. [css] 什么是脱离文档流?有什么办法可以让元素脱离标准的文档流?
  5. MongoDB Shell和Robo3T使用以及与SQL语法比较
  6. jq之animate() left font
  7. 谷歌YouTube算法团队:视频质量评价的集成池化方法
  8. ASP.NET MVC3 快速入门-第四节 添加一个模型(转)
  9. 多态与异常处理——动手动脑
  10. Clojure 1.7引入Transducers,提高跨平台支持度
  11. BAT 批处理的注释语句
  12. 量化交易学习——熟读github上的开源交易策略框架
  13. LZW算法原理及实现
  14. windows网络通讯端口
  15. 重构于 Vite:我如何做 SSG、静态资源发布以及自动化部署
  16. 抗混叠滤波matlab实现,采用抗混叠滤波器的高性能、12位、500 MSPS宽带接收机
  17. 2021春 算法复习
  18. 16周监考---期末考试...
  19. 腾讯云SOC方案入选CIC工信安全优秀解决方案
  20. ListView不能响应itemclick事件的解决方法

热门文章

  1. 数据挖掘和数据分析之数据中位数和众数
  2. qiankun微前端:script xxxxxx replaced by qiankun或script xxxxxxxxxx replaced by import-html-entry
  3. MiniUI快速入门教程(一)下载安装
  4. Python3实用安装教程
  5. 余承东再会张近东 战略合作升级点燃818第一把火
  6. 根据时间戳计算宝宝年龄(年月日)
  7. 记录我悲惨的一天(漏洞复现12小时,一个未成功)
  8. 【商业分析入门】共享办公是个好生意吗?——以优客工场为例
  9. 不卷不pua,早9晚6,这个招聘深得我心
  10. Object Detection in Foggy Conditions by Fusion of Saliency Map and YOLO