从左上角到右下角 棋盘问题_经典算法之棋盘覆盖问题 --分治法

分治法——棋盘覆盖问题

棋盘覆盖问题。有一个2k∗2k2k∗2k的方格棋盘,恰有一个方格是黑色的,其他为白色。你的任务是用包含3个方格的L型牌覆盖所有白色方格。黑色方格不能被覆盖,且任意一个白色方格不能同时被两个或更多牌覆盖。如图所示为L型牌的4种旋转方式。

分治三步骤

划分问题:将2k∗2k2k∗2k的棋盘划分为2k−1∗2k−12k−1∗2k−1这样的子棋盘4块。

递归求解:递归填充各个格子,填充分为四个情况,在下面会有解释,递归出口为k=0k=0也就是子棋盘方格数为1。

合并问题:不需要合并子问题。

递归填充的四种情况

如果黑方块在左上子棋盘,则递归填充左上子棋盘;否则填充左上子棋盘的右下角,将右下角看做黑色方块,然后递归填充左上子棋盘。

如果黑方块在右上子棋盘,则递归填充右上子棋盘;否则填充右上子棋盘的左下角,将左下角看做黑色方块,然后递归填充右上子棋盘。

如果黑方块在左下子棋盘,则递归填充左下子棋盘;否则填充左下子棋盘的右上角,将右上角看做黑色方块,然后递归填充左下子棋盘。

如果黑方块在右下子棋盘,则递归填充右下子棋盘;否则填充右下子棋盘的右下角,将左上角看做黑色方块,然后递归填充右下子棋盘。

棋盘覆盖问题分治算法

void chessBoard(int row, int column, int x, int y, int siz) {

// 递归出口

if(siz == 1) {

return;

}

// 对半划分成2^(siz - 1) * 2^(siz - 1)的棋盘

int s = siz / 2;

// L型牌编号自增

int t = ++number;

// 中间点,以此判别(x,y)在哪个子棋盘中

int centerRow = row + s;

int centerColumn = column + s;

// 黑色方格在左上子棋盘

if(x < centerRow && y < centerColumn) {

chessBoard(row, column, x, y, s);

} else {

// 不在则填充左上子棋盘的右下角

chess[centerRow - 1][centerColumn - 1] = t;

// 然后覆盖其他格子,注意这时(x,y)要看做已填充位置

chessBoard(row, column, centerRow - 1, centerColumn - 1, s);

}

// 黑色方格在右上子棋盘

if(x < centerRow && y >= centerColumn) {

chessBoard(row, centerColumn, x, y, s);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值