棋盤覆蓋問題:
問題描述:
現在有一個大小的棋盤,在棋盤內部有一隻特別的棋子,輸入的座標爲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;
}