棋盘覆盖问题:

问题描述

现在有一个大小的棋盘,在棋盘内部有一只特别的棋子,输入的坐标为X和Y。

要求尝试用4种不同类型的骨牌将棋盘覆盖,要求,骨牌之间不得重叠,并且骨牌不得覆盖特殊棋子,每个骨牌占用3个单位大小,形状如下。

棋盘假设如下:

思路分析:

对于这种题目,我们先从k=0开始分析:

当k=0的时候,棋盘大小为1,整个棋盘被特殊棋子覆盖。

当k=1的时候,棋盘大小为4,棋盘可以被一个骨牌外加一个特殊棋子覆盖

假设如下:


当k=2的时候,棋盘大小为16,棋盘可以被这样覆盖


当k=3的时候,棋盘可以被这样覆盖

 

 

 

 

第一次我写到这里的时候就发现,因为这个棋盘是

假设当我k=2的时候,棋盘大小是16,那么我可以将棋盘平均分成四块,每块大小是4,那么特殊棋子必须落在其中一个区域,这是,只要我让每一个区域的大小从4变成3,我就可以填满整个棋盘,所以可以选择在分界线填充骨牌。如下图:


那么,剩下的区域我都有相应的骨牌填充。

当k=3的时候,我们可以先把64的空间平均分成16*4,我们已经有一个区域有一个特殊棋子了,接下来,我们要把骨牌放在分界线上,让骨牌每一个单位成为新的假设的“特殊棋子”,这时候问题就变成了求4个棋盘大小为16的棋盘覆盖问题了。

以此类推…

实际上,这就是我们算法里面常见的分治算法,将一个问题分成若干个小问题,问题之间相互不影响,通过解决所有子问题实现求出主问题的办法。

 

代码如下:

[cpp] view plain copy print ?
  1. #define  _CRT_SECURE_NO_WARNINGS
  2. #include<iostream>
  3. #include<cstdlib>
  4. #include<cstring>
  5. usingnamespacestd;
  6. #defineMAX_SIZE100
  7. intboard[MAX_SIZE][MAX_SIZE];  /*definecheckerboard MAXSIZE = 64*64 */
  8. inttmp=1;
  9. intlocate(intdes_x,intdes_y,intlength,intx,inty)//指定棋子(des_x,des_y)的棋盘长度为length,左上角坐标为xy的位置
  10. {
  11. /*
  12. 只要将棋子所在区域标记为1234,用于判断与其他棋子的区域是否相同
  13. */
  14. if(des_x<length+x&&des_y<length+y)
  15. return1;
  16. if(des_x<length+x&&des_y>=length+y)
  17. return2;
  18. if(des_x>=length+x&&des_y<length+y)
  19. return3;
  20. if(des_x>=length+x&&des_y>=length+y)
  21. return4;
  22. return0;
  23. }
  24. voidcheckboard(intlength,intx,inty)//棋盘长度为length,棋盘最左上角的坐标为xy
  25. {
  26. if(length==2)
  27. {
  28. for(inti=x;i<x+length;i++)
  29. for(intj=y;j<y+length;j++)
  30. if(board[i][j]==-1)//是空,则直接覆盖
  31. board[i][j]=tmp;
  32. tmp++;
  33. }
  34. else
  35. {
  36. inti,j;
  37. intdir_x,dir_y;
  38. for(i=x;i<x+length;i++)
  39. for(j=y;j<y+length;j++)
  40. {
  41. if(board[i][j]!=-1)//找到非空棋子
  42. {
  43. dir_x=i;
  44. dir_y=j;
  45. }
  46. }
  47. length/=2;//下一次循环棋盘长度缩小为二分之一
  48. intmode=locate(dir_x,dir_y,length,x,y);//定位特殊棋子位置,此时(length+x,length+y)是中线
  49. for(i=x+length-1;i<=x+length;i++)//遍历分界线的四个棋子
  50. for(j=y+length-1;j<=x+length;j++)
  51. {
  52. if(locate(i,j,length,x,y)!=mode)//只要和特殊棋子不在同一区域就覆盖
  53. board[i][j]=tmp;
  54. }
  55. tmp++;
  56. checkboard(length,x,y);
  57. checkboard(length,x,y+length);
  58. checkboard(length,x+length,y);
  59. checkboard(length,x+length,y+length);
  60. }
  61. }
  62. intmain(void)
  63. {
  64. intsize,x,y,len;
  65. memset(board,-1,sizeof(board));
  66. cout<<"请输入棋盘大小的K值:"<<endl;
  67. cin>>len;
  68. size=(int)pow(2,len);
  69. cout<<"size = "<<size<<endl;
  70. cout<<"请输入特殊棋子的行坐标X(从0开始计算):";
  71. cin>>x;
  72. cout<<"请输入特殊棋子的列坐标y(从0开始计算):";
  73. cin>>y;
  74. board[x][y]=0;
  75. cout<<"x = "<<x<<" y = "<<y<<endl;
  76. checkboard(size,0,0);
  77. for(inti=0;i<size;i++)
  78. {
  79. for(intj=0;j<size;j++)
  80. {
  81. cout<<board[i][j]<<"\t";
  82. }
  83. cout<<endl;
  84. }
  85. cout<<endl;
  86. system("pause");
  87. return0;
  88. }

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdlib>
#include<cstring>
usingnamespacestd;
#defineMAX_SIZE100
intboard[MAX_SIZE][MAX_SIZE];  /*definecheckerboard MAXSIZE = 64*64 */
inttmp=1;intlocate(intdes_x,intdes_y,intlength,intx,inty)//指定棋子(des_x,des_y)的棋盘长度为length,左上角坐标为xy的位置
{/*只要将棋子所在区域标记为1234,用于判断与其他棋子的区域是否相同*/if(des_x<length+x&&des_y<length+y)return1;if(des_x<length+x&&des_y>=length+y)return2;if(des_x>=length+x&&des_y<length+y)return3;if(des_x>=length+x&&des_y>=length+y)return4;return0;
}voidcheckboard(intlength,intx,inty)//棋盘长度为length,棋盘最左上角的坐标为xy
{if(length==2){for(inti=x;i<x+length;i++)for(intj=y;j<y+length;j++)if(board[i][j]==-1)//是空,则直接覆盖board[i][j]=tmp;tmp++;}else{inti,j;intdir_x,dir_y;for(i=x;i<x+length;i++)for(j=y;j<y+length;j++){if(board[i][j]!=-1)//找到非空棋子{dir_x=i;dir_y=j;}}length/=2;//下一次循环棋盘长度缩小为二分之一intmode=locate(dir_x,dir_y,length,x,y);//定位特殊棋子位置,此时(length+x,length+y)是中线for(i=x+length-1;i<=x+length;i++)//遍历分界线的四个棋子for(j=y+length-1;j<=x+length;j++){if(locate(i,j,length,x,y)!=mode)//只要和特殊棋子不在同一区域就覆盖board[i][j]=tmp;}tmp++;checkboard(length,x,y);checkboard(length,x,y+length);checkboard(length,x+length,y);checkboard(length,x+length,y+length);}
}
intmain(void)
{intsize,x,y,len;memset(board,-1,sizeof(board));cout<<"请输入棋盘大小的K值:"<<endl;cin>>len;size=(int)pow(2,len);cout<<"size = "<<size<<endl;cout<<"请输入特殊棋子的行坐标X(从0开始计算):";cin>>x;cout<<"请输入特殊棋子的列坐标y(从0开始计算):";cin>>y;board[x][y]=0;cout<<"x = "<<x<<" y = "<<y<<endl;checkboard(size,0,0);for(inti=0;i<size;i++){for(intj=0;j<size;j++){cout<<board[i][j]<<"\t";}cout<<endl;}cout<<endl;system("pause");return0;
}

棋盘覆盖问题(分治)相关推荐

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

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

  2. 棋盘覆盖(分治典例)

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

  3. 递归与分治之棋盘覆盖问题

    在一个2^k * 2^k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘. 显然特殊方格在棋盘上出现的位置有4^k种情形.因而对任何k≥0,有4^k种不 ...

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

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

  5. 算法笔记 分治:循环赛日程 棋盘覆盖 选择问题 输油管问题 整数因子分解

    一.循环赛日程 #include <iostream> #include <vector> #include <string> #include <algor ...

  6. 算法系列(一):分治策略--棋盘覆盖

    算法系列(一):分治策略--棋盘覆盖 一.分析 问题描述:  图1-1 k=2时的一个特殊棋盘 在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其它方格不同,则称该方格为一特殊方格,且 ...

  7. 分治策略------棋盘覆盖(ChessBoard)

    棋盘覆盖原理 棋盘覆盖运用的是分治策略. 1.分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆盖问题. 2.k>0时, ...

  8. [分治] AOAPC2-ch8 棋盘覆盖问题

    题目 棋盘覆盖问题. 有一个2k∗2k2k∗2k2^{k}∗2^{k}的方格棋盘,恰有一个方格是黑色的,其他为白色.你的任务是用包含3个方格的L型牌覆盖所有白色方格.黑色方格不能被覆盖,且任意一个白色 ...

  9. 棋盘覆盖问题 java_Java基于分治算法实现的棋盘覆盖问题示例

    本文实例讲述了Java基于分治算法实现的棋盘覆盖问题.分享给大家供大家参考,具体如下: 在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其 ...

最新文章

  1. form的enctype和action
  2. 数字电子技术基础第三版杨志忠_阎石《数字电子技术基础》(第6版)笔记和课后习题(含考研真题)详解复习笔记资料...
  3. java多线程编程(一基础概念)
  4. ping源码分析(超详细,多图,带背景分析)
  5. 戴尔服务器重装系统蓝屏重启,戴尔电脑装系统蓝屏如何解决?
  6. Python词频统计与杨辉三角
  7. 电脑鼠标点一下就选很多程序
  8. winmerge对比时出现中文乱码的解决办法
  9. 阿里巴巴开源力作(二)--分布式流量卫兵Sentinel简介及控制台安装
  10. 2022中国眼博会,中国北京国际儿童青少年眼睛健康产业展览会
  11. 神通数据库connect by用法
  12. 详解EBS接口开发之销售订单挑库发放
  13. NET MVC5第三方验证——FluentValidation
  14. C语言学习宝典下载,C语言学习宝典
  15. python只读打开文件_关于python:只读文件的第一行?
  16. 装机员U盘安装Win10系统
  17. 靠收破烂年入60万的思维操作?究竟该怎么做呢?
  18. 金融项目学习——尚融宝
  19. 母牛生母牛,母牛生小牛。。。
  20. PowerBuilder 软件加密实验

热门文章

  1. 京东探索研究院NLP水平超越微软 织女Vega v1模型位居GLUE榜首
  2. 构建高并发高可用的电商平台架构实践(一)
  3. App自动化手机操作
  4. 正在通过app store进行鉴定解决方案
  5. 中国农药行业发展趋势及十四五产销需求预测报告2021-2027年版
  6. JSP常用标记——(web基础学习笔记)
  7. 全网最后一个免费版本,永久可用
  8. [机房测试]数字谜题
  9. Re:从零开始的DS学习 十大排序算法我都整理好了
  10. Intellij idea和eclipse快捷键—快速复制当前行到上一行或者下一行失效解决