棋盘覆盖问题:
问题描述:
现在有一个大小的棋盘,在棋盘内部有一只特别的棋子,输入的坐标为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;
}