棋盘覆盖问题(分治法)

棋盘覆盖问题(分治法)_第1张图片
裁判测试程序样例:

#include 
#include
#include 
#define MAX 1025
using namespace std;
int board[MAX][MAX];
int tile=1;

void ChessBoard(int tr,int tc,int dr,int dc,int size);

int main()
{
int dr,dc,size;
int j,i;
cin>>size;
cin>>dr>>dc;
ChessBoard(0,0,dr,dc,size);
for(i=0;i<size;i++){
  cout<<left; 
  for(j=0;j<size;j++)
  {
    cout<<setfill(' ')<<setw(5)<<board[i][j];
  }
  cout<<endl;
}
return 0;
} 

/* 请在这里填写答案 */

输入样例:

第一行输入一个数n表示棋盘大小,第二行输入特殊方格的行列下标。

8
1 2

输出样例:

输出棋盘。

3 3 4 4 8 8 9 9
3 2 0 4 8 7 7 9
5 2 2 6 10 10 7 11
5 5 6 6 1 10 11 11
13 13 14 1 1 18 19 19
13 12 14 14 18 18 17 19
15 12 12 16 20 17 17 21
15 15 16 16 20 20 21 21

idea

  • 问题描述
    棋盘覆盖问题(分治法)_第2张图片
    所谓棋盘覆盖问题,可以理解为正方形划分为若干个小正方形,其中一个被标记,需找出用不同角度的L型骨牌覆盖的方案。覆盖过程中需要满足覆盖除特殊方格外的所有方格,不能重叠

  • 问题有解性证明
    棋盘覆盖问题(分治法)_第3张图片

  • 分治法求解
    棋盘覆盖问题(分治法)_第4张图片

solution

void ChessBoard(int tr,int tc,int dr,int dc,int size){   
	if(size == 1) return;        //递归出口
    int t=tile++;            //取一个L型骨,其牌号为tile
    int s=size/2;            //分割棋盘
    //考虑左上角象限
    if(dr < tr + s && dc < tc + s)        //特殊方格在此象限中
		ChessBoard(tr, tc, dr, dc, s);
    else                //此象限中无特殊方格
    {    
		board[tr + s - 1][tc + s - 1] = t;    //用t号L型骨牌覆盖右下角
		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;        //用t号L型骨牌覆盖左下角
		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;      //用t号L型骨牌覆盖右上角
        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;      //用t号L型骨牌覆盖左上角
 		ChessBoard(tr + s, tc + s, tr + s, tc + s, s);      //将左上角作为特殊方格继续处理该象限
    }
}

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