[算法][遞歸] 棋盤覆蓋


 

>_<: 問題描述:

在一個2k×2k 個方格組成的棋盤中,恰有一個方格與其它方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。在棋盤覆蓋問題中,要用圖示的4種不同形態的L型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個L型骨牌不得重疊覆蓋。

>_<: 解決方法:

當k>0時,將2^k X 2^k 棋盤分割為4個2^(k-1) X 2^(k-1)子棋盤,特殊格必位於四塊小的棋盤之一中,其余3個子棋盤無特殊方格,為了將這3個無特殊的格子棋盤轉化為特殊棋盤,我們可以用一個L型的骨牌覆蓋這3個較小的企盼匯合處,從而將問題轉化為4個較小規模的企盼覆蓋問題,遞歸使用這種分割,直至棋盤划分為1的棋盤。

 1 #include<iostream>
 2 #include<iomanip>
 3 using namespace std;
 4 int tile=1;                   //L型骨牌的編號(遞增)
 5 int board[100][100];//棋盤
 6 /*****************************************************
 7 * 遞歸方式實現棋盤覆蓋算法
 8 * 輸入參數:
 9 * tr--當前棋盤左上角的行號
10 * tc--當前棋盤左上角的列號
11 * dr--當前特殊方格所在的行號
12 * dc--當前特殊方格所在的列號
13 * size:當前棋盤的:2^k
14 *****************************************************/
15 void chessBoard(int tr,int tc,int dr,int dc,int size){
16     if(size==1)//棋盤方格大小為1,說明遞歸到最里層
17         return;
18     int t=tile++;//每次遞增1
19     int s=size/2;//棋盤中間的行、列號(相等的)
20 
21     //檢查特殊方塊是否在左上角子棋盤中
22     if(dr<tr+s && dc<tc+s)//
23         chessBoard(tr,tc,dr,dc,s);
24     else{//不在,將該子棋盤右下角的方塊視為特殊方塊
25         board[tr+s-1][tc+s-1]=t;
26         chessBoard(tr,tc,tr+s-1,tc+s-1,s);
27     }
28 
29     //檢查特殊方塊是否在右上角子棋盤中
30     if(dr<tr+s && dc>=tc+s)//
31         chessBoard(tr,tc+s,dr,dc,s);
32     else{//不在,將該子棋盤左下角的方塊視為特殊方塊
33         board[tr+s-1][tc+s]=t;
34         chessBoard(tr,tc+s,tr+s-1,tc+s,s);
35     }
36 
37     //檢查特殊方塊是否在左下角子棋盤中
38     if(dr>=tr+s && dc<tc+s)//
39         chessBoard(tr+s,tc,dr,dc,s);
40     else{//不在,將該子棋盤右上角的方塊視為特殊方塊
41         board[tr+s][tc+s-1]=t;
42         chessBoard(tr+s,tc,tr+s,tc+s-1,s);
43     }
44 
45     //檢查特殊方塊是否在右下角子棋盤中
46     if(dr>=tr+s && dc>=tc+s)//
47         chessBoard(tr+s,tc+s,dr,dc,s);
48     else{//不在,將該子棋盤左上角的方塊視為特殊方塊
49         board[tr+s][tc+s]=t;
50         chessBoard(tr+s,tc+s,tr+s,tc+s,s);
51     }
52 }
53 
54 void main(){
55     while(true){
56         memset(board,0,sizeof(board));
57         tile=1;
58 
59         int size;
60 
61         cout<<"輸入棋盤的size(大小必須是2的n次冪): ";
62         cin>>size;
63         int index_x,index_y;
64         cout<<"輸入特殊方格位置的坐標: ";
65         cin>>index_x>>index_y;
66 
67         chessBoard (0,0,index_x,index_y,size);
68 
69         cout<<endl;
70         for(int i=0;i<size;i++){//輸出棋盤覆蓋
71             for(int j=0;j<size;j++ )
72                 cout<<setw(3)<<board[i][j]<<" ";
73             cout<<endl;
74         }
75         cout<<endl;
76     }
77 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM