棋盘覆盖问题

棋盘覆盖问题:

问题描述

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

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

棋盘覆盖问题_第1张图片

棋盘假设如下:

棋盘覆盖问题_第2张图片

思路分析:

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

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

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

假设如下:

棋盘覆盖问题_第3张图片

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

棋盘覆盖问题_第4张图片

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

 棋盘覆盖问题_第5张图片

 

 

 

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

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

棋盘覆盖问题_第6张图片

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

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

以此类推…

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

 

代码如下:

#define  _CRT_SECURE_NO_WARNINGS
#include
#include
#include
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+y)
        return2;
    if(des_x>=length+x&&des_y=length+x&&des_y>=length+y)
        return4;
    return0;
}
 
voidcheckboard(intlength,intx,inty)//棋盘长度为length,棋盘最左上角的坐标为xy
{
    if(length==2)
    {
        for(inti=x;i>len;
    size=(int)pow(2,len);
    cout<<"size = "<>x;
    cout<<"请输入特殊棋子的列坐标y(从0开始计算):";
    cin>>y;
    board[x][y]=0;
    cout<<"x = "<


你可能感兴趣的:(算法)