問題描述:
在乙個2^k×
2^k (k
≥0)個方格組成的棋盤中,恰有乙個方格與其他方格不同,稱該方格為特殊方格。顯然,特殊方格在棋盤中可能出現的位置有
4^k種,因而有
4^k種不同的棋盤,圖
(a)所示是
k=2時
16種棋盤中的乙個。棋盤覆蓋問題(
chess cover problem
)要求用圖
(b)所示的
4種不同形狀的
l型骨牌覆蓋給定棋盤上除特殊方格以外的所有方格,且任何2個
l型骨牌不得重疊覆蓋。
分治的技巧在於如何劃分棋盤,使劃分後的子棋盤的大小相同,並且每個子棋盤均包含乙個特殊方格,從而將原問題分解為規模較小的棋盤覆蓋問題。k>0時,可將
2^k×
2^k的棋盤劃分為4個
2^(k-1)×2^(
k-1)的子棋盤。這樣劃分後,由於原棋盤只有乙個特殊方格,所以,這
4個子棋盤中只有乙個子棋盤包含該特殊方格,其餘
3個子棋盤中沒有特殊方格。為了將這
3個沒有特殊方格的子棋盤轉化為特殊棋盤,以便採用遞迴方法求解,可以用乙個
l型骨牌覆蓋這
3個較小棋盤的會合處從而將原問題轉化為
4個較小規模的棋盤覆蓋問題。遞迴地使用這種劃分策略,直至將棋盤分割為1×
1的子棋盤。
實現分治演算法如下:
/*tr:棋盤左上角的行號
tc:棋盤左上角的列號
dr:特殊方格所在的行號
dc:特殊方格所在的列號
size= 2^k,棋盤規格*/
void chessboard(int tr,int tc,int dr,int dc,int size)
else
//覆蓋左下角棋盤
if(dr>=tr+s && dc=tr+s && dc>=tc+s)
else
}
程式完整**實現:
#includeusing namespace std;
#define n 1000
int tile=1;
int board[n][n];
void chessboard(int tr,int tc,int dr,int dc,int size)
else
//覆蓋左下角棋盤
if(dr>=tr+s && dc=tr+s && dc>=tc+s)
else
}int main()
{ int size;
cin>>size;
for(int i=0; i>dr>>dc;
chessboard(0,0,dr,dc,size);
for(int i=0; i
除錯案例:
若進一步理解遞迴完整過程,可用如下**實現:
//棋盤覆蓋
#includeusing namespace std;
#define n 1000
int tile=1;
int board[n][n];
/*tr:棋盤左上角的行號
tc:棋盤左上角的列號
dr:特殊方格所在的行號
dc:特殊方格所在的列號
size= 2^k,棋盤規格*/
void chessboard(int tr,int tc,int dr,int dc,int size)
{ if(size==1)
return ;
int t=tile++;//l型骨牌號
int s=size/2;
//覆蓋左上角子棋盤
if(dr=tc+s)
{cout<=tc+s)
{cout
for(int i=0; i>dr>>dc;
chessboard(0,0,dr,dc,size);
for(int i=0; i除錯案例:
分治 棋盤覆蓋
題目描述 在乙個2 k 2 k個方格組成的棋盤中,若恰有乙個方格與其它方格不同,則稱該方格為一特殊方格,稱改棋盤為一特殊棋盤。顯然特殊方格在棋盤上出現的位置有4 k種情形。因而對任何k 0,有4 k種不同的特殊棋盤。下圖所示的特殊棋盤為k 2時16個特殊棋盤中的乙個。在棋盤覆蓋問題中,要用下圖中4中...
棋盤覆蓋 分治
include pch.h include iostream using namespace std 棋盤問題,分治演算法 int q 1024 1024 棋盤陣列,全域性變數 static int tile 1 骨牌編號 tr 棋盤左上角行數,tc 棋盤左上角列數,dr 特殊方格所在行數,dc 特...
分治法,棋盤覆蓋
分治法 棋盤覆蓋問題 問題描述 在乙個2k x 2k 即 2 k x 2 k 個方格組成的棋盤中,恰有乙個方格與其他方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。在棋盤覆蓋問題中,要用4不同形態的l型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個l型骨牌不得重疊覆蓋。思想 將...