递归与分治算法-棋盘覆盖

博客围绕棋盘覆盖问题展开,要用4种L型骨牌覆盖特殊棋盘非特殊方格。介绍解题思路,将棋盘均分为四块,判断区域有无特殊方格,无则构造。给出棋盘参数,说明递归出口。还进行代码实现及相关思考,如找递归通式和出口等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

用4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。输入数据由程序运行后的界面中的编辑框中输入游戏规模,特殊方格的位置。将覆盖的结果在窗口中显示出来。

解题思路
有特殊方格----覆盖其他方格
无特殊方格----构造特殊方格----覆盖其他方格

(1)棋盘有以下参数:
         --棋盘大小2k×2k
         --棋盘边长为s=2k-1
         --棋盘顶点坐标 (tr,tc) [初始值一般为(0,0)]
         --特殊方格坐标 (dr,tc)
[注:棋盘大小在输入时可以有两种方式,一种是直接输入2k,此时需要输入的数值需为2的次方数,如2,4,8。另外一种方式是直接输入k,最好在输入时注明。]
(2)将棋盘均分为四块,并划分区域(顺序可自行调整)
在这里插入图片描述

①如何判断区域内是否含有特殊方格?
A区:dr<tr+s && dc<tc+s;
B区:dr>=tr+s && dc<tc+s;
C区:dr<tr+s && dc>=tc+s;
D区:dr>=tr+s && dc>=tc+s;

②如果区域内没有特殊方格,如何构造特殊方格?
A区:特殊方格坐标 (tr+s-1,tc+s-1) ;
B区:特殊方格坐标 (tr + s ,tc+s-1) ;
C区:特殊方格坐标 (tr+s-1,tc + s ) ;
D区:特殊方格坐标 (tr + s ,tc + s ) ;

③递归出口在哪里?
当s==1时,即棋盘无法再分割,即为递归出口。

代码实现

#include<iostream>		//小王的代码 
using namespace std;	//命名空间
int cnt=1;
int Board[100][100];
void qpfg(int tr,int tc,int dr,int dc,int size) //棋盘覆盖函数 
{
	if(size==1) return;				//如果棋盘无法再划分,返回 
	int s=size/2;					//设置有棋盘一半大小的中间变量 
	int t=cnt++;					//定义计数器 
	
	if(dr<tr+s && dc<tc+s)			//如果特殊方格在此棋盘中 
		qpfg(tr,tc,dr,dc,s);		//覆盖其他方格 
	else							//如果特殊方格不在此棋盘中 
	{
		Board[tr+s-1][tc+s-1]=t;	//构造特殊方格
		qpfg(tr,tc,tr+s-1,tc+s-1,s);//覆盖其他方格
	}
		 
	if(dr>=tr+s && dc<tc+s)			//如果特殊方格在此棋盘中 
		qpfg(tr+s,tc,dr,dc,s);		//覆盖其他方格 
	else							//如果特殊方格不在此棋盘中 
	{
		Board[tr+s][tc+s-1]=t;		//构造特殊方格
		qpfg(tr+s,tc,tr+s,tc+s-1,s);//覆盖其他方格
	} 
	
	if(dr<tr+s && dc>=tc+s)			//如果特殊方格在此棋盘中 
		qpfg(tr,tc+s,dr,dc,s);		//覆盖其他方格 
	else							//如果特殊方格不在此棋盘中 
	{
		Board[tr+s-1][tc+s]=t;		//构造特殊方格
		qpfg(tr,tc+s,tr+s-1,tc+s,s);//覆盖其他方格
	}
	
	if(dr>=tr+s && dc>=tc+s)		//如果特殊方格在此棋盘中 
		qpfg(tr+s,tc+s,dr,dc,s);	//覆盖其他方格 
	else							//如果特殊方格不在此棋盘中  
	{
		Board[tr+s][tc+s]=t;		//构造特殊方格
		qpfg(tr+s,tc+s,tr+s,tc+s,s);//覆盖其他方格
	}	
}

int main()
{
	int dr,dc,n;					//定义特殊方格横纵坐标、棋盘大小 
	cout<<"请输入棋盘大小:";
	cin>>n;							//n的值不用为2的次幂 
	int size=1;
	for(int a=1;a<=n;a++)			//size的值为2的n次幂 
		size*=2;
	cout<<endl;
	cout<<"请输入特殊方格的位置:";
	cin>>dr>>dc;
	cout<<endl;
	cout<<"您的棋盘为:"<<endl;
	qpfg(0,0,dr,dc,size);			//调用函数时直接给tc和tr赋值0 
	for(int i=0;i<size;i++)			//输出二维数组(即整个棋盘) 
	{
		for(int j=0;j<size;j++)
			cout<<Board[i][j]<<'\t';//'\t'可保证输出整齐 
			cout<<endl;
	}
	return 0;
} 

—关于棋盘覆盖算法的几点思考:
(1)对于使用递归算法求解的问题,我们只需找到递归通式和递归出口,千万不要试图层层追踪。
(2)有关 t 的取值问题:t 在程序中只有增值,没有减值,即 t 只会从 1 开始增加,但为什么在最大的划分区域中,构造的特殊方格值均为 1 ?
         ——在函数递归的退回过程中,可能要执行某些动作,包括回复在前行过程中存储起来的某些数据。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

和乐i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值