引子
棋盘覆盖问题采用的是分治策略。通过十字划分,将原问题转化为四个规模较小的棋盘覆盖问题。递归的使用这种分割,将问题最简化。
问题简述
在一个 2^k 2^k个方格组成的棋盘中,若恰有一个方格与其它方格不同,则称该方格为一特殊方格,称该棋盘为一特殊棋盘。显然特殊方格在棋盘上出现的位置有 4^k 种情形。因而对任何 k>=0 ,有 4^k 种不同的特殊棋盘。下图所示的特殊棋盘为 k=2 时 16 个特殊棋盘中的一个。在棋盘覆盖问题中,要用下图中 4 中不同形态的 L 型骨牌覆盖一个给定的特殊棋牌上除特殊方格以外的所有方格,且任何 2 个 L 型骨牌不得重叠覆盖。易知,在任何一个 2^k 2^k 的棋盘中,用到的 L 型骨牌个数恰为 (4^k-1)/3 。
题解
用分治策略,可以设计解棋盘问题的一个简捷的算法。
当k>0时,将2^k 2^k棋盘分割为4个2^(k-1) 2^(k-1)子棋盘,如下图所示。
特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,我们可以用一个L型骨牌覆盖这3个较小的棋盘的汇合处,如下图所示,这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原问题化为4个较小规模的棋盘覆盖问题。递归的使用这种分割,直至棋盘简化为1x1棋盘。
C++ Code
1 |
|
EGE演示程序
我自己用EGE做了一个图形化演示,但效果并不理想,代码核心内容如上,就不贴代码了。如图