`
switchlau
  • 浏览: 54409 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

分治法解决棋盘覆盖问题

阅读更多

http://www.hinn.cn/2008/04/chessboard_cover.html

在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。

    这里我们用分治法解决该问题。分治法是把一个规模很大的问题分解为多个规模较小、类似的子问题,然后递归地解决所有子问题,最后再由子问题的解决得到原问题的解决。
【解题思路】:将2^k x 2^k的棋盘,先分成相等的四块子棋盘,其中特殊方格位于四个中的一个,构造剩下没特殊方格三个子棋盘,将他们中的也假一个方格设为特殊方格。如果是:

左上的子棋盘(若不存在特殊方格)----则将该子棋盘右下角的那个方格假设为特殊方格
右上的子棋盘(若不存在特殊方格)----则将该子棋盘左下角的那个方格假设为特殊方格
左下的子棋盘(若不存在特殊方格)----则将该子棋盘右上角的那个方格假设为特殊方格
右下的子棋盘(若不存在特殊方格)----则将该子棋盘左上角的那个方格假设为特殊方格

当然上面四种,只可能且必定只有三个成立,那三个假设的特殊方格刚好构成一个L型骨架,我们可以给它们作上相同的标记。这样四个子棋盘就分别都和原来的大棋盘类似,我们就可以用递归算法解决。

代码如下:

#include<iostream.h>

int tile=1;

int board[100][100];

void chessBoard(int tr, int tc, int dr, int dc, int size)

{

       if(size==1)

              return;

       int t=tile++;

       int s=size/2;

       if(dr<tr+s && dc<tc+s)

              chessBoard(tr, tc, dr, dc, s);

       else

       {

              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

       {

              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

       {

              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

       {

              board[tr+s][tc+s]=t;

              chessBoard(tr+s, tc+s, tr+s, tc+s, s);

       }

}

 

void main()

{

       int size;

       cout<<"输入棋盘的size(大小必须是2的n次幂): ";

       cin>>size;

       int index_x,index_y;

       cout<<"输入特殊方格位置的坐标: ";

       cin>>index_x>>index_y;

       chessBoard(0,0,index_x,index_y,size);

       for(int i=0;i<size;i++)

       {

              for(int j=0;j<size;j++)

                     cout<<board[i][j]<<"\t";

              cout<<endl; 

       } 

}

 

分享到:
评论
1 楼 switchlau 2008-07-21  
转注:
board:表示棋盘
tile: 表示L型骨牌的编号

chessBoard函数的参数
tr: 棋盘左上角的行号
tc: 棋盘左上角的列号
dr: 特殊方格所在的行号
dc: 特殊方格所在的列号
size:2^k

相关推荐

    用 分治法 解决棋盘覆盖问题

    ### 使用分治法解决棋盘覆盖问题 #### 一、问题背景及定义 **棋盘覆盖问题**是在一个\(2^k \times 2^k\)的棋盘上,除去一个特殊的方格后,如何利用L型方块来完全覆盖剩余的区域。这里的L型方块是由三个单元格组成...

    MFC界面实现分治法解决棋盘覆盖算法的演示

    在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC) 库来实现一个界面,以演示通过分治法解决棋盘覆盖问题。MFC 是 Microsoft 提供的一个C++类库,它为开发者提供了一种构建Windows应用程序的框架,...

    算法设计与分析(用分治法求解棋盘覆盖问题)

    本篇将重点探讨如何利用分治策略来解决棋盘覆盖问题。棋盘覆盖问题是一个经典的组合优化问题,它在计算机科学、数学及理论物理等领域都有广泛的应用。 棋盘覆盖问题通常指的是将一个给定大小的棋盘用最少数量的棋子...

    分治法解决棋盘覆盖

    在分治法中解决棋盘覆盖问题,我们可以按照以下步骤进行: 1. **基础情况**:对于1×1的棋盘,只需要一个皇后就能完全覆盖。这是我们的基本情况,也是递归的终止条件。 2. **分解问题**:对于更大的棋盘,我们将...

    分治法-棋盘覆盖 java

    本文将详细介绍如何运用分治法解决“棋盘覆盖”这一经典问题,并给出相应的Java实现代码。 #### 二、问题定义 假设有一个\(2^k \times 2^k\)个方格组成的棋盘,其中恰好有一个特殊方格与众不同(通常表示为缺失或...

    棋盘覆盖问题 分治法——C++代码

    在解决棋盘覆盖问题时,分治法的应用是通过逐层放置皇后,每次处理一行,并确保当前行的皇后不会与前面行的皇后冲突。 以下是棋盘覆盖问题的分治算法步骤: 1. 选择棋盘的第一行,任意放置一个皇后。 2. 对于第二行...

    fenzhifa.rar_分治法 实现 棋盘覆盖

    在`2.cpp`这个文件中,可能包含了具体的C++代码实现,它展示了如何运用上述逻辑来解决棋盘覆盖问题。通过读取和理解这段代码,你可以看到如何使用递归函数来执行分治法,以及如何在子问题之间进行协调以确保覆盖的...

    分治法_棋盘覆盖(L型骨牌)

    棋盘覆盖问题是一个经典的分治法实例,通常涉及将一个大的棋盘(如8x8的国际象棋棋盘)用L型骨牌完全覆盖。L型骨牌由三块正方形组成,形状类似于英文字母L,可以覆盖住棋盘上的两个相邻格子。问题的关键在于如何使用...

    python实现棋盘覆盖问题.docx

    1. 使用分治法解决棋盘覆盖问题 分治法是将复杂的问题分解成若干个小问题,然后分别解决这些小问题。对于棋盘覆盖问题,我们可以将棋盘分割成四个大小相等的子棋盘,然后分别处理每个子棋盘。 2. 棋盘的表示 在 ...

    分治法案例-残缺棋盘覆盖问题-JAVA实现

    使用JAVA解决残缺棋盘覆盖问题:一个n*n的棋盘上有一个缺陷点,该点不能被覆盖,剩下的格子全部用三盒板覆盖。应用的是分治法。

    C++ 实现棋盘覆盖算法

    总结一下,使用C++和分治法解决棋盘覆盖问题涉及到以下几个关键知识点: 1. 分治法的概念和应用。 2. 递归函数的设计与实现。 3. 皇后冲突检测的算法。 4. 回溯法在搜索解决方案中的作用。 5. C++中的数据结构(如`...

    棋盘覆盖算法(分治算法)

    通过上述实现可以看出,使用分治算法解决棋盘覆盖问题是十分高效的。这种递归的策略不仅能够很好地解决问题,而且易于理解和实现。此外,这种方法还可以推广到其他类型的分治问题上,具有一定的普遍意义。

    计算机算法设计与分析课程设计.doc

    本文档包括了分治法解决棋盘覆盖问题和回溯法解决数字拆分问题两个部分。 分治法解决棋盘覆盖问题 分治法是一种常用的算法设计方法,它的基本思想是将一个复杂的问题分解成两个或更多的相同或相似的子问题,然后再...

    软件综合设计报告.rar

    总结来说,"软件综合设计报告"项目是一个结合了理论与实践的优秀示例,它展示了如何运用分治法解决棋盘覆盖问题,并通过Java编程语言和图形界面技术实现算法的动态展示。这样的设计不仅加深了对棋盘覆盖问题的理解,...

    棋盘覆盖与二分查找C++

    分治法解决棋盘覆盖与二分查找问题,C++描述.算法设计与分析经典例题

    使用分治递归来求解棋盘覆盖问题.zip

    棋盘覆盖问题是一个经典的...总的来说,分治递归在解决棋盘覆盖问题时展示了其高效性和灵活性。通过理解和掌握这种算法,开发者能够在面对类似问题时,快速设计出解决方案,这在实际的软件开发中具有广泛的应用价值。

    JAVA实现棋盘覆盖问题

    ### JAVA 实现棋盘覆盖问题 #### 知识点概览 ...通过上述分析可以看出,该程序成功实现了棋盘覆盖问题的解决方案,并利用了分治法的思想,借助Java语言的基础语法完成了一个实用而有趣的递归算法实现。

    实验4 分治法1

    **提高题:棋盘覆盖问题**:在一个2k×2k的棋盘中,除了一个特殊方格外,其余地方需要使用L型骨牌完全覆盖。这个问题可以通过递归的分治策略解决,每个2k×2k棋盘可以进一步划分为4个k×k的子棋盘。 **实验环境与...

Global site tag (gtag.js) - Google Analytics