棋盘覆盖问题(分治策略)

在棋盘覆盖问题中,可将棋盘转换为二维数组,通过改变元素值,从而实现棋盘覆盖,利用分治策略,不断将区域划分为四部分,在不同区域加入特殊点,直到覆盖整个棋盘。

一、题目重述
在一个2^k*2^k个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格且称该棋盘为一特殊棋盘。利用L型骨牌对特殊棋盘进行覆盖,要求骨牌不得重叠覆盖。
图1  k=2时的一个特殊棋盘
图1 k=2时的一个特殊棋盘
图2 四种L型骨牌
图2 四种L型骨牌
二、解决方案
用分治策略当k>0,将2^k*2^k棋盘等分割为4个2^(k-1) * 2^(k-1)子棋盘。特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格,为了将无特殊方格的子棋盘转化为特殊棋盘,可以利用一个L型骨牌覆盖这3个较小棋盘的会合处,如下图所示。
图3 棋盘分割
图3 棋盘分割(红色为特殊方格)
这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为1*1棋盘。
为了显示简单,我们将棋盘转化为二维数组,方格变换为数组元素,以0为初始化,以-1为特殊方格,以数字填充数组,同数字表示属于同一块L型骨牌,不同数字表示不同骨牌。
三、代码实现
1. 数据设置

const int number = 8;//棋盘列格数,注意要满足2^k=number,k为正整数
int C_B[number][number] = { 0 };//创建number*number的棋盘
static int temp = 1;//用于填补,作为L型骨牌
struct Point{
    int line;//行坐标
    int column;//列坐标
};

2.特殊点设置

Point set_point()//设置特殊点
{
    Point point;
    int temp = 0;
    cout << "请输入一个特殊点作为特殊方格(请输入 1 到 " << number*number << " 之间的数):";
    cin >> temp;
    point.line = (temp - 1) / number;//特殊点所在行,注意行和列均是从0开始算起,
    //之所以减一,是因为在number*k的数与number*k-1虽然在同一行,但除去 number时,却得到的是不同的值。为了改变这个临界,减一即可实现
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值