在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其它方格,如何覆盖。四个L型骨牌如下图:

棋盘覆盖问题(分治思想)_棋盘覆盖

       棋盘中的特殊方格如图:

棋盘覆盖问题(分治思想)_递归_02

 

       实现的基本原理是将2^k * 2^k的棋盘分成四块2^(k - 1) * 2^(k - 1)的子棋盘,特殊方格一定在其中的一个子棋盘中,如果特殊方格在某一个子棋盘中,继续递归处理这个子棋盘,直到这个子棋盘中只有一个方格为止如果特殊方格不在某一个子棋盘中,将这个子棋盘中的相应的位置设为骨牌号,将这个无特殊方格的了棋盘转换为有特殊方格的子棋盘,然后再递归处理这个子棋盘。以上原理如图所示:

棋盘覆盖问题(分治思想)_递归_03

      棋盘覆盖程序如下:

#include <iostream>       
using namespace std;   
  
int tile = 1;//全局变量 骨牌编号  
int Board[4][4];//棋盘  
void ChessBoard(int tr,int tc,int dr,int dc,int size);  
  
int main()  
{  
    for(int i=0; i<4; i++)  
    {  
        for(int j=0; j<4; j++)  
        {  
            Board[i][j] = 0;  
        }  
    }  
  
    ChessBoard(0,0,2,3,4);  
  
    for(int i=0; i<4; i++)  
    {  
        for(int j=0; j<4; j++)  
        {  
            cout<<Board[i][j]<<" ";  
        }  
        cout<<endl;  
    }  
}  
  
/** 
 * tr : 棋盘左上角的行号,tc棋盘左上角的列号 
 * dr : 特殊方格左上角的行号,dc特殊方格左上角的列号 
 * size :size = 2^k 棋盘规格为2^k*2^k 
 */  
void ChessBoard(int tr,int tc,int dr,int dc,int size)  
{  
    if(size == 1)  
    {  
        return;  
    }  
    int t = tile++;//L型骨牌编号  
    int s = size/2;//分割棋盘  
  
    //覆盖左上角子棋盘  
    if(dr<tr+s && dc<tc+s)//特殊方格在此棋盘中  
    {  
        ChessBoard(tr,tc,dr,dc,s);  
    }  
    else//特殊方格不在此棋盘中  
    {  
        //用编号为t的骨牌覆盖右下角  
        Board[tr+s-1][tc+s-1] = t;  
        //覆盖其余方格  
        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//特殊方格不在此棋盘中  
    {  
        //用编号为t的骨牌覆盖左下角  
        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//特殊方格不在此棋盘中  
    {  
        //用编号为t的骨牌覆盖右上角  
        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//特殊方格不在此棋盘中  
    {  
        //用编号为t的骨牌覆盖左上角  
        Board[tr+s][tc+s] = t;  
        //覆盖其余方格  
        ChessBoard(tr+s,tc+s,tr+s,tc+s,s);  
    }  
  
}  

 

 

 

 

      程序运行结果如下:

 

棋盘覆盖问题(分治思想)_i++_04