分治法之棋盤覆蓋

2021-06-22 00:50:56 字數 1634 閱讀 4630

一、問題描述 

在乙個2k x 2k ( 

即:2^k x 2^k )

個方格組成的棋盤中,恰有乙個方格與其他方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。在棋盤覆蓋問題中,要用圖示的

4種不同形態的

l型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個

l型骨牌不得重疊覆蓋。

二、演算法思路

實現的基本原理是將2^k * 2^k的棋盤分成四塊2^(k - 1) * 2^(k - 1)的子棋盤,特殊方格一定在其中的乙個子棋盤中,如果特殊方格在某乙個子棋盤中,繼續遞迴處理這個子棋盤,直到這個子棋盤中只有乙個方格為止如果特殊方格不在某乙個子棋盤中,將這個子棋盤中的相應的位置設為骨牌號,將這個無特殊方格的了棋盤轉換為有特殊方格的子棋盤,然後再遞迴處理這個子棋盤。

值得一提的是如何確定乙個2^k * 2^k的有特殊塊的棋盤呢? 1)棋盤左上角的座標 2)棋盤中特殊塊的座標  3)k的數值

這樣乙個大的棋盤被 劃分成a b c d四個小的棋盤,依次判斷特殊塊(紅色)是否在子棋盤中,若在子棋盤中,則直接遞迴求解該棋盤。

若不在子棋盤中,則在把「相應」的塊標記為特殊塊(黃色),再繼續遞迴求解。

遞迴的邊界條件是該棋盤中只有乙個塊。

偽**描述:

static int count=0;

void  chessboard(int startx, int starty ,int specialx , int speialy,  int size)

三、**實現

#include #include using namespace std;

int k;

int size;

static int count=0;

int arr[100][100];

void chessboard(int startx,int starty, int specialx, int specialy, int size)

if(specialx>=startx+mid&&specialy=startx+mid&&specialy>=starty+mid)

chessboard(startx+mid,starty+mid,specialx,specialy,mid);

else }

int main()

{ memset(arr,0,sizeof(int)*100*100);

cin>>k;

size=(int)pow((double)2,(double)k);

chessboard(0,0,0,0,size);

int i,j;

for(i=0;i

為什麼不是 

0 2 3 3

2 2 1 3

4 1 1 5

4 4 5 5

這是因為第13行**int t=++count的位置

如果將13行**放在15行之後,就可以得到如下結果

分治法,棋盤覆蓋

分治法 棋盤覆蓋問題 問題描述 在乙個2k x 2k 即 2 k x 2 k 個方格組成的棋盤中,恰有乙個方格與其他方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。在棋盤覆蓋問題中,要用4不同形態的l型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個l型骨牌不得重疊覆蓋。思想 將...

分治法 棋盤覆蓋

問題描述 在乙個2 k 2 k個方格組成的棋盤中,有乙個方格與其它的不同,若使用以下四種l型骨牌覆蓋除這個特殊方格的其它方格,如何覆蓋。l型 棋盤 基本原理 實現的基本原理是將2 k 2k的棋盤分成四塊2 k 1 2 k 1 的子棋盤,特殊方格一定在其中的乙個子棋盤中,如果特殊方格在某乙個子棋盤中,...

棋盤覆蓋(分治法)

include define maxnum 100 最大規模 using namespace std 變數設定 di 特定棋子橫座標 dj 特定棋子縱座標 hi 棋盤左上角橫座標 hj 棋盤左上角縱座標 tile 棋子序號 board 棋盤 maxnum 棋盤最大規模 int board maxnu...