遞迴與分治中的棋盤覆蓋問題

2021-08-08 11:50:34 字數 1572 閱讀 4803

演算法,新開的課之一,老師也還挺有意思,所以聽課的積極性也較高些。其中摘取了遞迴與分治內容中的棋盤覆蓋問題。

先看下問題:。

在乙個2^k * 2^k 個方格組成的棋盤中,給定任意乙個特殊方格,用四種不同形態的l型骨牌覆蓋乙個給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個l型骨牌不得重疊。

對於圖中給出的k為2例子,可以試出骨牌放置的位置。但當k值更大時就尷尬了。我們都希望把大事化小,不難發現,當乙個特殊方格存在於乙個2*2的棋盤內,l型骨牌的排放位置是唯一的。那麼以上圖為例,可以確定左上角的骨牌,則整個棋盤的左上角也隨之確定。

進而我們希望把其他部分可以與左上角一樣容易確定,所以利用分治的方法,將棋盤分為4個2*2的小棋盤,希望能達到與左上部分類似的情況,這時又可以發現,由於左上部分存在特殊方格,而除左上部分後,中間又有三個方格可以組成l型,將這三個方格視為各自2*2的特殊方格後,各自方格內又出現與左上類似的情況。

所以我們以此類推,2^k*2^k的棋盤可依次4分,每一次設最中間除特殊方格所在子棋盤外的3個方格為特殊方格,直至子棋盤為2*2。

**實現:

對於乙個語言掌握不太熟練的人來說,實現乙個實際問題的**可以說時很頭疼的一件事。

我想首先必須要做的就是判斷特殊方格在哪個位置,而對比的方法則可以通過最左上角的方格的位置和當前子棋盤的行列數的和進行比對(當然筆者認為如果用其他方格位置進行比對也可以,只是左上角更簡便些),如果在左上子棋盤,則遞迴即可,若不在,則需要將之前所說的3個方格標為特殊方格。

標記時為了方便區分,每次標記時用不同數字,這個在每次遞迴一開始設定乙個+1的變數即可。

處理完這些,大概思路也就清晰了,最終**如下。

#include #include int tile=1;

int board[100][100];

void chessboard(int tr,int tc,int dr,int dc,int size)

if(dr>=tr+s&&dc=tr+s&&dc>=tc+s)

chessboard(tr+s,tc+s,dr,dc,s);

else

}int main()

{ int i,j,m,tr=0,tc=0,dr=0,dc=1,size;

printf("請輸入棋盤行列的m值:");

scanf("%d",&m);

size=m;

printf("棋盤行列數為%d\n",m);

memset(board,0,sizeof(board));

chessboard(tr,tc,dr,dc,size);

for(i=0;i

因為本人水平有限,僅是演算法的初學者,文中內容難免有錯誤不足,懇請各位批評改正,也歡迎與我一同交流,共同學習進步。

棋盤覆蓋問題(遞迴與分治)

棋盤覆蓋問題。有乙個2k 2k2k 2k的方格棋盤,恰有乙個方格是黑色的,其他為白色。你的任務是用包含3個方格的l型牌覆蓋所有白色方格。黑色方格不能被覆蓋,且任意乙個白色方格不能同時被兩個或更多牌覆蓋。如圖所示為l型牌的4種旋轉方式。當乙個黑塊位於某一角時,可以解決乙個邊長為2的正方形匹配。可是這樣...

棋盤覆蓋問題(分治,遞迴)

在乙個2 k 2 k個方格組成的棋盤中,恰有乙個方格與其他方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。該棋盤為特殊棋盤,紅色的方格為特殊方格。棋盤覆蓋問題是指,要用圖2中的4種不同形態的l型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個l型骨牌不得重疊覆蓋。該問題就是在考察...

遞迴與分治之棋盤覆蓋問題

在乙個2 k 2 k個方格組成的棋盤中,若有乙個方格與其他方格不同,則稱該方格為一特殊方格,且稱該棋盤為乙個特殊棋盤。顯然特殊方格在棋盤上出現的位置有4 k種情形.因而對任何k 0,有4 k種不同的特殊棋盤。下圖所示的特殊棋盤為 k 2 時 16 個特殊棋盤中的乙個。在棋盤覆蓋問題中,要用下圖中 4...