分治法之棋盘覆盖问题
写此博文目的:
1.刚学了棋盘覆盖问题,自己实现它,加深自己的理解很感悟
2.给为棋盘问题困惑的朋友带来一点思路
开始分析!
什么叫做分治法呢?
:简单来说就是分而治之,先把问题分解成很多个小问题,然后再处理它
棋盘覆盖问题就是一个很经典的分治问题
首先我们先来看一下棋盘覆盖问题到底是个什么问题?
题目引用自:https://blog.csdn.net/acm_jl/article/details/50938164
思路分析:
将一个大的棋盘划分为相同大小的四块,在这四块相同大小的子棋盘中,现在只有一个子棋盘有一个格子是不可覆盖的,还有三个子棋盘是所有的格子都是可以覆盖的,所以我们需要为这3个不存在不可覆盖格子的子棋盘构造3个不可覆盖的格子,那么我们应该如何构造呢?
下面我们看一张图:
假如现在第一个不可覆盖的格子在左上角,那么我们需要构造的3个不可覆盖的格子就跟上面的图一样,构造的这3个不可覆盖的格子的连接成的形状肯定是个L型,只是会随着棋盘中不可覆盖的格子的位置的不同而L型的开口方向会有所变化
总结一下:
将2k∗2k2k∗2k的棋盘划分为2k−1∗2k−12k−1∗2k−1这样的子棋盘4块。递归填充各个格子,填充分为四个情况,归出口为s=0,s=0也就是子棋盘方格数为1。
递归的四种情况:
如果黑方块在左上子棋盘,则递归填充左上子棋盘;否则填充左上子棋盘的右下角,将右下角看做黑色方块,然后递归填充左上子棋盘。
如果黑方块在右上子棋盘,则递归填充右上子棋盘;否则填充右上子棋盘的左下角,将左下角看做黑色方块,然后递归填充右上子棋盘。
如果黑方块在左下子棋盘,则递归填充左下子棋盘;否则填充左下子棋盘的右上角,将右上角看做黑色方块,然后递归填充左下子棋盘。
如果黑方块在右下子棋盘,则递归填充右下子棋盘;否则填充右下子棋盘的右下角,将左上角看做黑色方块,然后递归填充右下子棋盘。
好啦,话不多说,我们直接撸代码吧!!!
1 #include<stdio.h> 2 #define max 1024 3 int cb[max][max];//最大棋盘 4 int id=0;//覆盖标志位 5 int chessboard(int tr,int tc,int dr,int dc,int size)//tr,tc代表棋盘左上角的位置,dr ,dc代表棋盘不可覆盖点的位置,size是棋盘大小 6 { 7 if(size==1)//如果递归到某个时候,棋盘大小为1,则结束递归 8 { 9 return 0; 10 } 11 int s=size/2;//使得新得到的棋盘为原来棋盘大小的四分之一 12 int t=id++; 13 if(dr<tr+s&&dc<tc+s)//如果不可覆盖点在左上角,就对这个棋盘左上角的四分之一重新进行棋盘覆盖 14 { 15 chessboard(tr,tc,dr,dc,s); 16 }else//因为不可覆盖点不在左上角,所以我们要在左上角构造一个不可覆盖点 17 { 18 cb[tr+s-1][tc+s-1]=t;//构造完毕 19 chessboard(tr,tc,tr+s-1,tc+s-1,s);//在我们构造完不可覆盖点之后,棋盘的左上角的四分之一又有了不可覆盖点,所以就对左上角棋盘的四分之一进行棋盘覆盖 20 } 21 22 if(dr<tr+s&&dc>=tc+s)//如果不可覆盖点在右上角,就对这个棋盘右上角的四分之一重新进行棋盘覆盖 23 { 24 chessboard(tr,tc+s,dr,dc,s); 25 }else//因为不可覆盖点不在右上角,所以我们要在右上角构造一个不可覆盖点 26 { 27 cb[tr+s-1][tc+s]=t; 28 chessboard(tr,tc+s,tr+s-1,tc+s,s);//在我们构造完不可覆盖点之后,棋盘的右上角的四分之一又有了不可覆盖点,所以就对右上角棋盘的四分之一进行棋盘覆盖 29 } 30 31 32 if(dr>=tr+s&&dc<tc+s)//如果不可覆盖点在左下角,就对这个棋盘左下角的四分之一重新进行棋盘覆盖 33 { 34 chessboard(tr+s,tc,dr,dc,s); 35 }else//因为不可覆盖点不在左下角,所以我们要在左下角构造一个不可覆盖点 36 { 37 cb[tr+s][tc+s-1]=t; 38 chessboard(tr+s,tc,tr+s,tc+s-1,s);//在我们构造完不可覆盖点之后,棋盘的左下角的四分之一又有了不可覆盖点,所以就对左下角棋盘的四分之一进行棋盘覆盖 39 } 40 41 if(dr>=tr+s&&dc>=tc+s)//如果不可覆盖点在右下角,就对这个棋盘右下角的四分之一重新进行棋盘覆盖 42 { 43 chessboard(tr+s,tc+s,dr,dc,s); 44 }else//因为不可覆盖点不在右下角,所以我们要在右下角构造一个不可覆盖点 45 { 46 cb[tr+s][tc+s]=t; 47 chessboard(tr+s,tc+s,tr+s,tc+s,s);//在我们构造完不可覆盖点之后,棋盘的右下角的四分之一又有了不可覆盖点,所以就对右下角棋盘的四分之一进行棋盘覆盖 48 } 49 50 //后面的四个步骤都跟第一个类似 51 } 52 int main() 53 { 54 printf("请输入正方形棋盘的大小(行数):\n"); 55 int n; 56 scanf("%d",&n); 57 printf("请输入在%d*%d棋盘上不可覆盖点的位置:\n",n,n); 58 int i,j,k,l; 59 scanf("%d %d",&i,&j); 60 printf("不可覆盖点位置输入完毕,不可覆盖点的值为-1\n"); 61 cb[i][j]=-1; 62 chessboard(0,0,i,j,n); 63 for(k=0;k<n;k++) 64 { 65 printf("%2d",cb[k][0]); 66 for(l=1;l<n;l++) 67 { 68 printf(" %2d",cb[k][l]); 69 } 70 printf("\n"); 71 } 72 return 0; 73 }
代码分析:
我们先看chessboard函数
函数的主干是四个if else循环,也就是说只会执行一个if中的语句,但是会执行3个else中的语句,这3个else中的语句就是构造不可覆盖格子,然后对含有新构造的不可覆盖点的子棋盘来重写进行棋盘覆盖,也就是递归调用棋盘覆盖函数,递归的结束条件就是子棋盘只有一个格子,也就是s=1,每次调用棋盘覆盖函数,都要进行s=size/2,目的就是把一个大棋盘划分为四个相同大小的子棋盘。
运行结果:
不足错误的地方,欢迎各位拍砖指正哦!!!!!
技术在于分享
转载于:https://www.cnblogs.com/yinbiao/p/8666209.html
分治法之棋盘覆盖问题相关推荐
- 分治法解决棋盘覆盖问题
分治法解决棋盘覆盖问题 问题描述: 在一个2k×2k(k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格.显然,特殊方格在棋盘中出现的位置有4k中情形,因而有4k中不同的棋盘. ...
- 【分治法】棋盘覆盖问题java实现
文章目录 问题描述 问题分析 算法设计 java代码 问题描述 在一个2k × 2k个放个中,恰好只有一个方格是残缺的.也就是在这个棋盘中有一个方格与其它的格子不同, 我们称这种棋盘为残缺棋盘. 下图 ...
- 「分治法」棋盘覆盖问题
一.问题描述 在一个2k×2 k(k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格. 棋盘覆盖问题要求用图所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格, ...
- 分治法:快速排序棋盘覆盖
目标 使用分治法解决快速排序问题 使用分治法解决棋盘覆盖问题 原理 一.快排原理 排序算法在工作中最常用,也是学习很多其他算法的前置知识,例如在运用二分查找算法之前,我们通常需要保证数据是有序的,如果 ...
- java棋盘覆盖分治法,棋盘覆盖-分治法
信 息 工 程 学 院 算法分析 实习报告 学院:信息工程学院 班级:软件工程083 姓名: 学号: 成绩: 一.实习题目 : 棋盘覆盖 二.实习过程 : 1.了解分治法的思想: 将一个难以解决的大问 ...
- 计算机基础算法棋盘覆盖,分治算法求解棋盘覆盖问题互动教学过程.doc
分治算法求解棋盘覆盖问题互动教学过程 分治算法求解棋盘覆盖问题互动教学过程 摘要:针对算法设计与分析课程难度较大.对学生编程能力要求较高的现状,通过对棋盘覆盖问题的分治算法求解过程进行互动教学设计,引 ...
- 棋盘覆盖问题--分治策略
问题描述: 在一个2k×2k (k≥0,k为上标)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格.棋盘覆盖问题要求用图(b)所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外 ...
- python棋盘覆盖问题,python实现棋盘覆盖问题及可视化
问题介绍 棋盘覆盖问题,是一种编程问题. 如何应用分治法求解棋盘覆盖问题呢?分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆 ...
- python棋盘覆盖问题,python怎么实现棋盘覆盖问题及可视化
python怎么实现棋盘覆盖问题及可视化 发布时间:2021-03-12 17:04:06 来源:亿速云 阅读:94 作者:TREX 这篇文章主要介绍"python怎么实现棋盘覆盖问题及可视 ...
- 棋盘覆盖-经典的分治法问题
棋盘覆盖-经典的分治法问题 一.问题概述 二.适用方法 三.代码展示 四.运行结果 五.算法分析 一.问题概述 在一个 2k×2k个方格组成的棋盘中,若恰有一个方格与其他方格不同,称该方格为特殊方格, ...
最新文章
- Gut:卡姆果提取物改变肠道菌群预防小鼠肥胖
- 数据结构(严蔚敏)之三——顺序栈之c语言实现
- 转载:opencv中imshow函数运行中断的解决办法
- shell 当中的比较运算
- java实例分析宠物商店_java实例分析:宠物商店.ppt
- html页面判断其他div为空,将外部html加载到div - 页面加载然后变为空白
- linux查看系统启动时间
- iOS FFmpeg 优秀博客(资源)集锦
- 部署war包到tomcat根目录
- 【python】将图片格式转换为RGB格式
- deepin有线网卡无法连接网络
- 约瑟夫环两种解题方式
- ProLiant 380G5服务器上安装netware4.11
- 计算机word水印在哪,word中如何加入水印的两种方法
- JavaScript中的模块化开发
- 到底什么样的网站才需要办理ICP许可证?
- Hessian矩阵正定与函数凹凸性的关系
- 青云很忙 QingCloud Insight 2017开幕倒计时
- java文档注释用什么开头,极其重要
- 关于单片机代码的风格
热门文章
- mysql数据上传apache_配置Apache服务器 数据库mySQL
- 不知道如何实现服务的动态发现?快来看看 Dubbo 是如何做到的
- Spring Framework 常用工具类一
- 阶段5 3.微服务项目【学成在线】_day04 页面静态化_12-页面静态化-页面静态化流程...
- ES6深入浅出-1 新版变量声明:let 和 const-2.视频 let和const
- 2010年ImagineCup,我们共同走过
- django-admin源码解析
- IOS VFL语言(页面布局)
- (转)在NGUI使用图片文字(数字、美术字)(直接可用于UILable)
- BZOJ5312 冒险 势能分析、线段树