高效算法设计_递归与分治(棋盘覆盖问题,循环日程表,巨人与鬼)

递归与分治

棋盘覆盖问题

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

[][]—— [][]—— []——— []
[] ———[]—— [][]— —[][]
(1)——(2) —— (3)—— (4)

思路:

分治:划分,递归求解(递归边界,k=1时一块牌就够了),合并。 (信了他的邪!)


左上角(r1,c1)
|——(r1+half_size-1,c1+half_size-1) |(r1+half_size,c1+half_size-1)
|——————————————中心点————————————
|——(r1+half_size,c1+half_size-1) | (r1+half_size,c1+half_size)


输入:
输出:
#include <stdio.h>

#define BOARD_SIZE 4
int board[BOARD_SIZE][BOARD_SIZE];
int g_domino_num;

// c1, r1: 棋盘左上角的行号和列号
// c2, r2: 特殊方格的行号和列号
// size = 2 ^ k
void chessboard(int r1, int c1, int r2, int c2, int size)//提前手算好要不要-1非常重要。
{
    if(1 == size) return;
    int half_size;
    int d = g_domino_num++;
    half_size = size / 2;

    if(r2 < r1 + half_size && c2 < c1 + half_size) //特殊方格在左上角子棋盘
    {
       chessboard(r1, c1, r2, c2, half_size);
    }
    else   // 不在此棋盘,将此棋盘右下角设为相应的骨牌号
    {
       board[r1 + half_size - 1][c1 + half_size - 1] = d;
       chessboard(r1, c1, r1 + half_size - 1, c1 + half_size - 1, half_size);
    }

    if(r2 < r1 + half_size && c2 >= c1 + half_size) //特殊方格在右上角子棋盘
    {
       chessboard(r1, c1 + half_size, r2, c2, half_size);
    }
    else  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值