棋盤覆蓋

在一個2k x 2k ( 即:2^k x 2^k )個方格組成的棋盤中,恰有一個方格與其餘方格不一樣,稱該方格爲一特殊方格,且稱該棋盤爲一特殊棋盤。在棋盤覆蓋問題中,要用圖示的4種不一樣形態的L型骨牌覆蓋給定的特殊棋盤上除特殊方格之外的全部方格,且任何2個L型骨牌不得重疊覆蓋,用到的方格數爲(4^k-1)/3
 
 
  
 
    這裏咱們用分治法解決該問題。分治法是把一個規模很大的問題分解爲多個規模較小、相似的子問題,而後遞歸地解決全部子問題,最後再由子問題的解決獲得原問題的解決。
【解題思路】:將2^k x 2^k的棋盤,先分紅相等的四塊子棋盤,其中特殊方格位於四個中的一個,構造剩下沒特殊方格三個子棋盤,將他們中的也假一個方格設爲特殊方格。若是是:
左上的子棋盤(若不存在特殊方格)----則將該子棋盤右下角的那個方格假設爲特殊方格
右上的子棋盤(若不存在特殊方格)----則將該子棋盤左下角的那個方格假設爲特殊方格
左下的子棋盤(若不存在特殊方格)----則將該子棋盤右上角的那個方格假設爲特殊方格
右下的子棋盤(若不存在特殊方格)----則將該子棋盤左上角的那個方格假設爲特殊方格
爲了將這三個無特殊方格的子棋盤轉化爲特殊棋盤,能夠用一個L型骨牌覆蓋這三個較小棋盤的 匯合處,如圖B所示,這三個子棋盤上被L型骨牌覆蓋的方格就成爲該棋盤的特殊方格,從而將原問題轉化爲4個較小規模的棋盤覆蓋問題。遞歸的使用這種分割直至棋盤分割爲1*1棋盤。
 固然上面四種,只可能且一定只有三個成立,那三個假設的特殊方格恰好構成一個L型骨架,咱們能夠給它們做上相同的標記。這樣四個子棋盤就分別都和原來的大棋盤相似,咱們就能夠用遞歸算法解決。
代碼以下:
 1 #include<iostream.h>
 2 int tile=1;
 3 int board[100][100];
 4 void chessBoard(int tr, int tc, int dr, int dc, int size)
 5 {
 6        if(size==1)
 7               return;
 8        int t=tile++;//L型骨牌號
 9        int s=size/2;//分割棋盤
10        if(dr<tr+s && dc<tc+s)//若是棋盤在左上角中
11               chessBoard(tr, tc, dr, dc, s);//分割左上角棋盤
12        else
13        {
14               board[tr+s-1][tc+s-1]=t;//用t號覆蓋右下角
15               chessBoard(tr, tc, tr+s-1, tc+s-1, s);//覆蓋其餘方格
16        }
17        if(dr<tr+s && dc>=tc+s)//若是棋盤在右上角中
18               chessBoard(tr, tc+s, dr, dc, s); //分割右上角棋盤
19        else
20        {
21               board[tr+s-1][tc+s]=t;//用t號覆蓋左上角
22               chessBoard(tr, tc+s, tr+s-1, tc+s, s);//覆蓋其餘方格
23        }
24        if(dr>=tr+s && dc<tc+s)//若是棋盤在左下角中
25               chessBoard(tr+s, tc, dr, dc, s);//分割左下角棋盤
26        else
27        {
28               board[tr+s][tc+s-1]=t;//用t號覆蓋右上角
29               chessBoard(tr+s, tc, tr+s, tc+s-1, s);//覆蓋其餘方格
30        }
31        if(dr>=tr+s && dc>=tc+s)//若是棋盤在右下角中
32               chessBoard(tr+s, tc+s, dr, dc, s);//分割右下角棋盤
33        else
34        {
35               board[tr+s][tc+s]=t;//用t號覆蓋左上角
36               chessBoard(tr+s, tc+s, tr+s, tc+s, s);//覆蓋其餘方格
37        }
38 }
39  
40 void main()
41 {
42        int size;
43        cout<<"輸入棋盤的size(大小必須是2的n次冪): ";
44        cin>>size;
45        int index_x,index_y;
46        cout<<"輸入特殊方格位置的座標: ";
47        cin>>index_x>>index_y;
48        chessBoard(0,0,index_x,index_y,size);
49        for(int i=0;i<size;i++)
50        {
51               for(int j=0;j<size;j++)
52                      cout<<board[i][j]<<"\t";
53               cout<<endl; 
54        } 
55 }
相關文章
相關標籤/搜索