【問題】在乙個2k×2k (k≥0)個方格組成的棋盤中,恰有乙個方格與其他方格不同,稱該方格為特殊方格。顯然,特殊方格在棋盤中可能出現的位置有4k種,因而有4k種不同的棋盤,圖4.10(a)所示是k=2時16種棋盤中的乙個。棋盤覆蓋問題(chess cover problem)要求用圖4.10(b)所示的4種不同形狀的l型骨牌覆蓋給定棋盤上除特殊方格以外的所有方格,且任何2個l型骨牌不得重疊覆蓋。
【想法】如何應用分治法求解棋盤覆蓋問題呢?分治的技巧在於如何劃分棋盤,使劃分後的子棋盤的大小相同,並且每個子棋盤均包含乙個特殊方格,從而將原問題分解為規模較小的棋盤覆蓋問題。k>0時,可將2k×2k的棋盤劃分為4個2k-1×2k-1的子棋盤,如圖4.11(a)所示。這樣劃分後,由於原棋盤只有乙個特殊方格,所以,這4個子棋盤中只有乙個子棋盤包含該特殊方格,其餘3個子棋盤中沒有特殊方格。為了將這3個沒有特殊方格的子棋盤轉化為特殊棋盤,以便採用遞迴方法求解,可以用乙個l型骨牌覆蓋這3個較小棋盤的會合處,如圖4.11(b)所示,從而將原問題轉化為4個較小規模的棋盤覆蓋問題。遞迴地使用這種劃分策略,直至將棋盤分割為1×1的子棋盤。
c程式設計實現:
#include #include #define n 100
int board[n][n];
int t;
void chessboard(int tr, int tc, int dr, int dc, int size)
if (dr < tr + s && dc >= tc + s) //特殊方格在右上角子棋盤中
chessboard(tr, tc+s, dr, dc, s); //遞迴處理子棋盤
else
if (dr >= tr + s && dc < tc + s) //特殊方格在左下角子棋盤中
chessboard(tr+s, tc, dr, dc, s); //遞迴處理子棋盤
else
if (dr >= tr + s && dc >= tc + s) //特殊方格在右下角子棋盤中
chessboard(tr+s, tc+s, dr, dc, s); //遞迴處理子棋盤
else
}void print(int n){
int i,j;
for (i=0;i
棋盤覆蓋問題
source code include include include using namespace std const int n 1024 int board n n count void cover int sx,int sy,int cx,int cy,int size,int cx1,i...
棋盤覆蓋問題
棋盤覆蓋問題 time limit 1000ms,special time limit 2500ms,memory limit 32768kb total submit users 103,accepted users 40 problem 10432 no special judgement pr...
棋盤覆蓋問題
author tanky woo blog www.wutianqi.com 棋盤覆蓋問題 分治法2010 12 3 include using namespace std const int n 11 int board n n int tile 0 tr 棋盤左上角方格的行號 tc 棋盤左上角方...