分治策略——棋盘覆盖问题

一.问题描述

一个2k*2k的棋盘,指定一点为特殊方格(无需覆盖),然后用(4k-1)/3个L型骨牌无重叠地覆盖其余所有方格。下图为一个示例:

分治策略——棋盘覆盖问题_第1张图片

二.算法思想——分治策略

将一个规模为n问题分为k个规模较小的子问题,这些子问题互相独立且与原问题相同,递归或迭代地解这些子问题,再将子问题合并得到原问题的解。

以一个实例说明棋盘覆盖问题的分治思想。

分治策略——棋盘覆盖问题_第2张图片

上图为 2 3 ∗ 2 3 2^3*2^3 2323的棋盘,黑色方格为指定特殊方格。

第一次分割后形成4个 2 2 ∗ 2 2 2^2*2^2 2222的棋盘,需要为没有特殊方格的棋盘指定特殊方格(保证子问题互相独立且与原问题相同),即黄色的1部分(这样指定刚好是一个L型骨牌)。

第二次分割以右上角 2 2 ∗ 2 2 2^2*2^2 2222棋盘为例,分割后形成4个2*2的棋盘,同样为没有特殊方格的棋盘指定特殊方格(白色的2部分)。

最终,2*2的棋盘再覆盖一次即可完成。在指定特殊方块的过程中,问题规模也越来越小,依次完成上左、上右、下左、下右四个期棋盘的覆盖(顺序可任意规定)后,大棋盘的覆盖也就随之完成。

代码实现可分为三步:分割棋盘(规模缩小一倍),判定特殊方格的位置(将特殊方格的坐标与棋盘中间坐标对比)、根据比较结果决定对应棋盘用不用增添特殊方格。

3.算法时间复杂度的递推式

T ( k ) = { O ( 1 ) , k=0 4 T ( k − 1 ) + O ( 1 ) , k>1 T(k) = \begin{cases} O(1), & \text{k=0} \\ 4T(k-1)+O(1),&\text{k>1} \end{cases} T(k)={ O(1),4T(k1)+O(1),k=0k>1

三.程序代码

#include

int tile=1; 					//L型骨牌序号 
int board[128][128]; 			//二维数组模拟棋盘 

//(tr,tc)表示棋盘的左上角坐标(即确定棋盘位置),size=2^k确定棋盘大小;(tc,dc)表示特殊方块的位置 
void chessBoard(int tr,int tc,int dr,int dc,int size){
      
	//递归出口 
	if(size==1)
		return; 

	//分割棋盘 
	int s=size/2;	
	int t=tile++;		//t记录本层骨牌序号	
	//判断特殊方格在不在左上棋盘 
	if(dr<tr+s&&dc<tc+s){
          
		chessBoard(tr,tc,dr,dc,s); 	//特殊方格在左上棋盘的递归处理方法 
	}else{
     
		board[tr+s-1][tc+s-1]=t;					//不在左上棋盘的话,其特殊方块位于中点(tr+s,tc+s)的左上方 
		chessBoard(tr,tc,tr+s-1,tc+s-1,s);			//特殊方格不在左上棋盘的递归处理方法 
	}
	
	//判断特殊方格在不在右上棋盘 
	if(dr<tr+s&&dc>=tc+s){
     		
		chessBoard(tr,tc+s,dr,dc,s); 
	}else{
     
		board[tr+s-1][tc+s]=t;
		chessBoard(tr,tc+s,tr+s-1,tc+s,s); 
	} 
	
	//判断特殊方格在不在左下棋盘 
	if(dr>=tr+s&&dc<tc+s){
     			
		chessBoard(tr+s,tc,dr,dc,s); 
	}else{
     
		board[tr+s][tc+s-1]=t;
		chessBoard(tr+s,tc,tr+s,tc+s-1,s); 
	}
	
	//判断特殊方格在不在右下棋盘
	if(dr>=tr+s&&dc>=tc+s){
     	
		chessBoard(tr+s,tc+s,dr,dc,s); 
	}else{
     
		board[tr+s][tc+s]=t;
		chessBoard(tr+s,tc+s,tr+s,tc+s,s); 
	}
} 

int main(){
     
	chessBoard(0,0,5,5,8);		//(0,0)为顶点,大小为8的棋盘; 特殊方块位于(5,5)
	int i,j;
	printf("\n\n\n");
	for(i=0;i<8;i++){
     			//输出棋盘内容
		for(j=0;j<8;j++){
     
			printf("%d\t",board[i][j]);
		}
		printf("\n\n\n");
	}
	return 0;
}

你可能感兴趣的:(笔记,算法)