递归与分治
棋盘覆盖问题
题目:有一个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