棋盘覆盖问题

问题描述:在一个2k×2k (k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。棋盘覆盖问题要求用图4.11(b)所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。


(a) k=2时的一种棋盘                                   (b)  4种不同形状的L型骨牌

                        

                                       

                        


算法思路:采用分治法,特殊方格必位于 4 个较小子棋盘之一中,其余 3 个子棋盘中无特殊方格。为了将这 3 个无特殊方格的子棋盘转化为特殊棋盘,我们可以用一个 L 型骨牌覆盖这 3 个较小的棋盘的汇合处,如下图所示,这 3 个子棋盘上被 L 型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原问题化为 4 个较小规模的棋盘覆盖问题。递归的使用 这种分割,直至棋盘简化为 1x1 棋盘。



C语言代码如下(在devC++编译运行通过):

#include <stdio.h>

#include <stdlib.h>

int flag=1;
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) 
        return; 
     int t=flag++;
     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);                              
         }
}


int main()
{
  int size,i,j;
  printf("输入棋盘的size(大小必须是2的n次幂): ");
  scanf("%d",&size);    
  int x,y;
  printf("输入特殊方格位置的坐标: ");
  scanf("%d%d",&x,&y);
  chessBoard(0,0,x,y,size);
  for(i=0;i<size;i++){
   for(j=0;j<size;j++)
     printf("%-4d", board[i][j]);
   printf("\n");
  }
  system("pause");
  return 0;
}

猜你喜欢

转载自blog.csdn.net/lzkIT/article/details/14414293