夜深人靜寫算法——棋盤覆蓋問題(分治)

棋盤覆蓋問題:

問題描述

現在有一個大小的棋盤,在棋盤內部有一隻特別的棋子,輸入的座標爲X和Y。

要求嘗試用4種不同類型的骨牌將棋盤覆蓋,要求,骨牌之間不得重疊,並且骨牌不得覆蓋特殊棋子,每個骨牌佔用3個單位大小,形狀如下。

      (a)                                                      (b)                                       (c)                                    (d)

(1)  採用分治的方法,將大小的棋盤分成四等份,如圖(a)

(2)因爲初始棋盤只有一份是存在棋子的,所以將剩下的三部分相鄰的三個角組成一個骨牌的形狀(a,b,c,d中的一種),如圖b

(3)重複操作(1), 直到棋盤大小爲2。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h> 
#include <time.h>
#include <string.h>
#define LENGTH 8 //棋盤大小 
using namespace std;
int number = 2;  
 
bool check(int  list[LENGTH][LENGTH],int r,int c,int l){//判斷當前的棋盤裏是否存在棋子。
	for(int i = r;i < r + l;i++)
		for(int j = c; j < c + l ;j++ )
			if(list[i][j] > 0)
				return false;   
	return true;
}
template <class Type>
void chessboard (Type list[LENGTH][LENGTH] ,int r,int c,int l){
	if(l == 2){  //如果棋盤大小爲2,就將棋盤的沒有填的棋子填滿
			for(int i = r;i < r + l; i++)
				for(int j = c; j < c + l ;j++){
					if(list[i][j] == 0)
					list[i][j] = number; 
				} 
			++number;
			
	}else{
		if(check(list,r,c,l/2)){ 	  //判斷左上角的部分是否存在棋子
			list[r + l/2-1][c + l/2 - 1] = number ;
		}		 
		if(check(list,r,c + l/2,l/2)) //判斷右上角的部分是否存在棋子
		{
			list[r + l/2 - 1][c + l/2] = number;
		}
			
		if(check(list,r + l/2,c,l/2)){ //判斷左下角的部分是否存在棋子
			list[r + l/2][c + l/2 - 1] = number;
		}
			
		if(check(list,r + l/2,c + l/2,l/2)){//判斷右下角的部分是否存在棋子
			list[r + l/2][c + l/2] = number;
		}
				
		++number;		
		chessboard(list,r,c,l/2);           //左上角遞歸
		chessboard(list,r,c + l/2,l/2);      //右上角遞歸
		chessboard(list,r + l/2,c,l/2);       //左下角遞歸 
		chessboard(list,r + l/2,c + l/2,l/2);  //右下角遞歸
				
	}
};
template <class Type>
void show(Type list[LENGTH][LENGTH]){
	for(int i = 0;i < LENGTH;i++){
		for(int j = 0; j < LENGTH ; j++){
			printf("%6d",list[i][j]);
		}
		cout<<endl;
	}
}
int main(){
	int xo,yo;
	srand(time(NULL));xo = rand()%10;yo = rand()%10;
	
	int list[LENGTH][LENGTH];
	memset(list,0,sizeof list);
	list[xo][yo] = 1;
	
	cout<<"初始棋盤:\n"; 
	show(list);
	
	chessboard(list,0,0,LENGTH);
	
	cout<<"覆蓋後的棋盤: \n";
	show(list);
 
	return 0;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章