棋盘覆盖问题----分治法

参考blog

棋盘覆盖问题

问题描述

在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其它方格,如何覆盖。四个L型骨牌如下图:

L型骨牌

棋盘中的特殊方格如图:

棋盘

        实现的基本原理是将 2k x 2k 的棋盘分成四块 2(k-1) x 2(k-1)的子棋盘,特殊方格一定在其中的一个子棋盘中,如果特殊方格在某一个子棋盘中,继续递归处理这个子棋盘,直到这个子棋盘中只有一个方格为止如果特殊方格不在某一个子棋盘中,将这个子棋盘中的相应的位置设为骨牌号,将这个无特殊方格的了棋盘转换为有特殊方格的子棋盘,然后再递归处理这个子棋盘。以上原理如图所示:

存在一个方格

棋盘覆盖程序如下:

//2d6 棋盘覆盖问题
#include "stdafx.h"
#include <iostream>     
using namespace std; 

int tile = 1;//全局变量 骨牌编号
int Board[4][4];//棋盘
void ChessBoard(int tr,int tc,int dr,int dc,int size);

int main()
{
    for(int i=0; i<4; i++)
    {
        for(int j=0; j<4; j++)
        {
            Board[i][j] = 0;
        }
    }

    ChessBoard(0,0,2,3,4);

    for(int i=0; i<4; i++)
    {
        for(int j=0; j<4; j++)
        {
            cout<<Board[i][j]<<" ";
        }
        cout<<endl;
    }
}

/**
 * tr : 棋盘左上角的行号,tc棋盘左上角的列号
 * dr : 特殊方格左上角的行号,dc特殊方格左上角的列号
 * size :size = 2^k 棋盘规格为2^k*2^k
 */
void ChessBoard(int tr,int tc,int dr,int dc,int size)
{
    if(size == 1)
    {
        return;
    }
    int t = tile++;//L型骨牌编号
    int s = size/2;//分割棋盘

    //覆盖左上角子棋盘
    if(dr<tr+s && dc<tc+s)//特殊方格在此棋盘中
    {
        ChessBoard(tr,tc,dr,dc,s);
    }
    else//特殊方格不在此棋盘中
    {
        //用编号为t的骨牌覆盖右下角
        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//特殊方格不在此棋盘中
    {
        //用编号为t的骨牌覆盖左下角
        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//特殊方格不在此棋盘中
    {
        //用编号为t的骨牌覆盖右上角
        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//特殊方格不在此棋盘中
    {
        //用编号为t的骨牌覆盖左上角
        Board[tr+s][tc+s] = t;
        //覆盖其余方格
        ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
    }

}

程序运行结果如下:


输出结果

思考

第一步(寻求最小的求解) :

2x2

当只有2x2时,刚好一个L型骨牌 + 特殊方格(任意4个角都可) 。可是暂时看不到如何扩张,所以得考虑4x4的模型。

4x4

棋盘

1.可以分割成4 个 2x2,分别为左上角,右上角,左下角和右下角。
2.右上角可以直接用2x2情况求解,可是其他3块2x2右得按什么 有序步骤 求解?
既然是分治法必然会用到递归,那么大问题必然分解为N个重复可解的小问题(当然小问题的类型个数要可控,一般为1到4个)


数学模型:

g(x) = af1(x) + bf2(x) + cf3(x) + df4(x), 其中fi(x)为可解的小问题,a,b,c,d为小问题重复的次数


根据公式,我们可以
1.先找各f(x)
2.将f(x)相加成g(x)


1.现阶段我们已经分解为2个小问题:

f1(x) :存在特殊方格的2x2棋盘的求解
f2(x) : 3个没有特殊方格的2x2棋盘的求解

  1. 当然f1(x)已经解决,接着考虑f2(x)。

2.1 考虑f1(x)在4x4的左上角

f2(x)

如图是f2(x)求解,
f2(x)解步骤 :1.每个2x2先放一个L型骨牌(缺口朝向中央,也只能这样放),2.在中央放一块L型骨牌(缺口朝向存在特殊方格的2x2棋盘)

2.2 考虑f1(x)在4x4的其他角落块,同2.1。

第一步 结尾

那么此时我们已经找到了f(x)并都得到了有序解步骤:
f1(x) :存在特殊方格的2x2棋盘的求解
f2(x) : 3个没有特殊方格的2x2棋盘的求解

第二步(组合f(x)来求解g(x)) :

我们将f(x)来接下 8x8时的情况:
分解成4块4x4,存在特殊方格的4x4棋盘同第一步分析求解,可是其他3块4x4不能分解成f2(x) ,所以现在的f1(x) 和f2(x)不满足,从新第一步,求f(x)

重复第一步 :

观察现有的f1(x) 和f2(x)
f1(x) 无法更改
f2(x) 可考虑。同时在8x8中也是f2(x)不满足,那么我们得出一套满足各2k x 2k有序解步骤

其实有2个解决口:
1.将f2(x)步骤颠倒试试
2.在2k x 2k中分解的每个2(k-1) x 2(k-1)棋盘必然应该是相同操作的,那么得出每个2x2棋盘也应该是同f1(x),那么就是给没有特殊方格的2x2棋盘各个一个特殊方块(同时3个特殊方块也可以组成一个L型骨牌)

新的f(x)
f1(x) :存在特殊方格的2x2棋盘的求解
f2(x) : 3个没有特殊方格的2x2棋盘各给一个特殊方块(同时3个特殊方块也可以组成一个L型骨牌),变成f1(x)的求解

f2(x) =f3(x) + 3 *f1(x)

f3(x) : 3个没有特殊方格的2x2棋盘各给一个特殊方块(同时3个特殊方块也可以组成一个L型骨牌)

进入第二步

进行归纳法

先证明4x4依据2x2可解,再证明2k x 2k 的棋盘依据 2(k-1) x 2(k-1)的棋盘可解得出f(x)满足需求

那么递归项就是
f1(x) +f2(x) = f1(x) +f3(x) + 3 *f1(x) = f3(x) + 4 * f1(x)
在f1(x) 合并时,要将 f3(x) 提前,因为有3 *f1(x) 在 f3(x) 后

接下来就可以根据有序的解步骤写程序了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 分治策略 本文包括分治的基本概念二分查找快速排序归并排序找出伪币棋盘覆盖最大子数组 源码链接:https://gi...
    廖少少阅读 1,842评论 0 7
  • Tags: 算法 棋盘覆盖问题 【问题描述】 在一个2^k×2^k个方格组成的棋盘中,若有一个方格与其他方格不同,...
    zhwhong阅读 6,205评论 4 16
  • 机器学习是做NLP和计算机视觉这类应用算法的基础,虽然现在深度学习模型大行其道,但是懂一些传统算法的原理和它们之间...
    在河之简阅读 20,491评论 4 65
  • 在最初設定目標的時候,袁導曾經說過:“只要你們願意去拼搏,我陪著你們去打市場,林先生留在家裡講沙龍,提升整體的品質...
    粟莎阅读 134评论 0 0
  • №1 导语乡土是中国基层社会的代名词,它意指中国铺陈在土地上的广大农村。在传统中国,农村尽管是社会的基层,却是整个...
    冰叶Irene阅读 5,184评论 1 10