夜深人静写算法——棋盘覆盖问题(分治)

棋盘覆盖问题:

问题描述

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值