棋盤覆蓋問題

【問題】在一個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 <stdio.h>
#include <stdlib.h>

#define N 100
int board[N][N];
int t;

void chessBoard(int tr, int tc, int dr, int dc, int size)
{
	int s, t1; //t1表示本次覆蓋所用L型骨牌的編號
	if (size == 1) return; //棋盤只有一個方格且是特殊方格
	t1 = ++t; // L型骨牌編號
	s = size/2; // 劃分棋盤
	if (dr < tr + s && dc < tc + s) //特殊方格在左上角子棋盤中
		chessBoard(tr, tc, dr, dc, s); //遞歸處理子棋盤
	else{ //用 t1號L型骨牌覆蓋右下角,再遞歸處理子棋盤
		board[tr + s - 1][tc + s - 1] = t1;
		chessBoard(tr, tc, tr+s-1, tc+s-1, s); 
	}
	if (dr < tr + s && dc >= tc + s) //特殊方格在右上角子棋盤中
		chessBoard(tr, tc+s, dr, dc, s); //遞歸處理子棋盤
	else { //用 t1號L型骨牌覆蓋左下角,再遞歸處理子棋盤
		board[tr + s - 1][tc + s] = t1;
		chessBoard(tr, tc+s, tr+s-1, tc+s, s); 
	}
	if (dr >= tr + s && dc < tc + s) //特殊方格在左下角子棋盤中
		chessBoard(tr+s, tc, dr, dc, s); //遞歸處理子棋盤
	else { //用 t1號L型骨牌覆蓋右上角,再遞歸處理子棋盤
		board[tr + s][tc + s - 1] = t1;
		chessBoard(tr+s, tc, tr+s, tc+s-1, s);
	}
	if (dr >= tr + s && dc >= tc + s) //特殊方格在右下角子棋盤中
		chessBoard(tr+s, tc+s, dr, dc, s); //遞歸處理子棋盤
	else { //用 t1號L型骨牌覆蓋左上角,再遞歸處理子棋盤
		board[tr + s][tc + s] = t1;
		chessBoard(tr+s, tc+s, tr+s, tc+s, s); 
	}
}
void print(int n)
{
	
	int i,j;
	for (i=0;i<n;i++)
	{
		for (j=0;j<n;j++)
			if(j==n-1){
				printf("%d\n",board[i][j]);
			}else{
				printf("%d,",board[i][j]);
			}
	}
}
void main(){
	int tr,tc,dr,dc,size;
	tr=0;
	tc=0;
	printf("輸入棋盤大小:");
	scanf("%d",&size);
	printf("輸入特殊棋盤位置,如輸入:1,1:");
	scanf("%d,%d",&dr,&dc);
	board[dr-1][dc-1]=0;
	chessBoard(tr,tc,dr-1,dc-1,size);
	print(size);
}



發佈了24 篇原創文章 · 獲贊 17 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章