首页 > 代码库 > 棋盘覆盖

棋盘覆盖

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

四各L型骨牌如下图1



      图1  


棋盘中的特殊方格如图2





图2

实现的基本原理是将2^k * 2^k的棋盘分成四块2^(k - 1) * 2^(k - 1)的子棋盘,特殊方格一定在其中的一个子棋盘中,

如果特殊方格在某一个子棋盘中,继续递归处理这个子棋盘,直到这个子棋盘中只有一个方格为止;

如果特殊方格不在某一个子棋盘中,将这个子棋盘中的相应的位置设为骨牌号,将这个无特殊方格的了棋盘转换为有特殊方格的子棋盘,然后再递归处理这个子棋盘。

以上原理如图3所示。






图3

将棋盘保存在一个二维数组中。骨牌号从1开始,特殊方格为0,如果是一个4 * 4的棋盘,特殊方格为(2,2),那么程序的输出为

2   2   3   3   
2   1   1   3   
4   1   0   5   
4   4   5   5

     
相同数字的为同一骨牌。

 

#include<iostream>using namespace std;int tile=1;                   //L型骨牌的编号(递增)int board[100][100];  //棋盘/****************************************************** 递归方式实现棋盘覆盖算法* 输入参数:* tr--当前棋盘左上角的行号* tc--当前棋盘左上角的列号* dr--当前特殊方格所在的行号* dc--当前特殊方格所在的列号* size:当前棋盘的:2^k*****************************************************/void chessBoard ( int tr, int tc, int dr, int dc, int size ){    if ( size==1 )    //棋盘方格大小为1,说明递归到最里层        return;    int t=tile++;     //每次递增1    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;        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 );    }}void main(){    int size;    cout<<"输入棋盘的size(大小必须是2的n次幂): ";    cin>>size;    int index_x,index_y;    cout<<"输入特殊方格位置的坐标: ";    cin>>index_x>>index_y;    chessBoard ( 0,0,index_x,index_y,size );    for ( int i=0; i<size; i++ )    {        for ( int j=0; j<size; j++ )            cout<<board[i][j];        cout<<endl;    }}

 

棋盘覆盖