写此博文目的:

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

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

  1. 分治法解决棋盘覆盖问题

    分治法解决棋盘覆盖问题 问题描述: 在一个2k×2k(k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格.显然,特殊方格在棋盘中出现的位置有4k中情形,因而有4k中不同的棋盘. ...

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

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

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

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

  4. 分治法:快速排序棋盘覆盖

    目标 使用分治法解决快速排序问题 使用分治法解决棋盘覆盖问题 原理 一.快排原理 排序算法在工作中最常用,也是学习很多其他算法的前置知识,例如在运用二分查找算法之前,我们通常需要保证数据是有序的,如果 ...

  5. java棋盘覆盖分治法,棋盘覆盖-分治法

    信 息 工 程 学 院 算法分析 实习报告 学院:信息工程学院 班级:软件工程083 姓名: 学号: 成绩: 一.实习题目 : 棋盘覆盖 二.实习过程 : 1.了解分治法的思想: 将一个难以解决的大问 ...

  6. 计算机基础算法棋盘覆盖,分治算法求解棋盘覆盖问题互动教学过程.doc

    分治算法求解棋盘覆盖问题互动教学过程 分治算法求解棋盘覆盖问题互动教学过程 摘要:针对算法设计与分析课程难度较大.对学生编程能力要求较高的现状,通过对棋盘覆盖问题的分治算法求解过程进行互动教学设计,引 ...

  7. 棋盘覆盖问题--分治策略

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

  8. python棋盘覆盖问题,python实现棋盘覆盖问题及可视化

    问题介绍 棋盘覆盖问题,是一种编程问题. 如何应用分治法求解棋盘覆盖问题呢?分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆 ...

  9. python棋盘覆盖问题,python怎么实现棋盘覆盖问题及可视化

    python怎么实现棋盘覆盖问题及可视化 发布时间:2021-03-12 17:04:06 来源:亿速云 阅读:94 作者:TREX 这篇文章主要介绍"python怎么实现棋盘覆盖问题及可视 ...

  10. 棋盘覆盖-经典的分治法问题

    棋盘覆盖-经典的分治法问题 一.问题概述 二.适用方法 三.代码展示 四.运行结果 五.算法分析 一.问题概述 在一个 2k×2k个方格组成的棋盘中,若恰有一个方格与其他方格不同,称该方格为特殊方格, ...

最新文章

  1. Gut:卡姆果提取物改变肠道菌群预防小鼠肥胖
  2. 数据结构(严蔚敏)之三——顺序栈之c语言实现
  3. 转载:opencv中imshow函数运行中断的解决办法
  4. shell 当中的比较运算
  5. java实例分析宠物商店_java实例分析:宠物商店.ppt
  6. html页面判断其他div为空,将外部html加载到div - 页面加载然后变为空白
  7. linux查看系统启动时间
  8. iOS FFmpeg 优秀博客(资源)集锦
  9. 部署war包到tomcat根目录
  10. 【python】将图片格式转换为RGB格式
  11. deepin有线网卡无法连接网络
  12. 约瑟夫环两种解题方式
  13. ProLiant 380G5服务器上安装netware4.11
  14. 计算机word水印在哪,word中如何加入水印的两种方法
  15. JavaScript中的模块化开发
  16. 到底什么样的网站才需要办理ICP许可证?
  17. Hessian矩阵正定与函数凹凸性的关系
  18. 青云很忙 QingCloud Insight 2017开幕倒计时
  19. java文档注释用什么开头,极其重要
  20. 关于单片机代码的风格

热门文章

  1. mysql数据上传apache_配置Apache服务器 数据库mySQL
  2. 不知道如何实现服务的动态发现?快来看看 Dubbo 是如何做到的
  3. Spring Framework 常用工具类一
  4. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_12-页面静态化-页面静态化流程...
  5. ES6深入浅出-1 新版变量声明:let 和 const-2.视频 let和const
  6. 2010年ImagineCup,我们共同走过
  7. django-admin源码解析
  8. IOS VFL语言(页面布局)
  9. (转)在NGUI使用图片文字(数字、美术字)(直接可用于UILable)
  10. BZOJ5312 冒险 势能分析、线段树