洛谷【P1228 地毯填补问题】【棋盘覆盖】 {分治|递归} 奋斗的珂珂~

在这里插入图片描述在这里插入图片描述在这里插入图片描述

解题思路

典型的分治问题:棋盘覆盖。
首先,需要将棋盘分割成为4个2(k-1)*2(k-1)的小棋盘。
在这里插入图片描述

那么公主的位置必然在这四个方格之内,其余三个方格中没有被占用的位置。要将这三个没被占用位置的子方格转化为被占用位置的子方格,可以使用一个“L”型骨牌覆盖在这三个子方格的汇合之处。如下图:
在这里插入图片描述

进而将原问题转化为4个较小规模的棋盘覆盖问题,递归这种分割,直至棋盘转化为1*1的棋盘。

完整代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 

void deal(int a,int b,int x,int y,int len)//a,b代表当前棋盘的左上角顶点,m,n代表障碍点 
{
	if(len==1) return ;
	len>>=1;//len除以2
	if(x<=a+len-1&&y<=b+len-1)//障碍点在左上角的棋盘 
	{
		printf("%d %d 1\n",a+len,b+len);
		deal(a,b,x,y,len);
		deal(a,b+len,a+len-1,b+len,len);
		deal(a+len,b,a+len,b+len-1,len);
		deal(a+len,b+len,a+len,b+len,len); 
	 } 
	 else if(x<=a+len-1&&y>b+len-1)//障碍点在右上角棋盘
	 {
	 	printf("%d %d 2\n",a+len,b+len-1);
	 	deal(a,b,a+len-1,b+len-1,len);
	 	deal(a,b+len,x,y,len);
	 	deal(a+len,b,a+len,b+len-1,len);
	 	deal(a+len,b+len,a+len,b+len,len);
	}	
	else if(x>a+len-1&&y<=b+len-1)//障碍在左下角棋盘 
	{
		printf("%d %d 3\n",a+len-1,b+len);
		deal(a,b,a+len-1,b+len-1,len);
		deal(a,b+len,a+len-1,b+len,len);
		deal(a+len,b,x,y,len);
		deal(a+len,b+len,a+len,b+len,len);
	}
	else{//障碍在右下角棋盘 
		printf("%d %d 4\n",a+len-1,b+len-1);
		deal(a,b,a+len-1,b+len-1,len);
		deal(a,b+len,a+len-1,b+len,len);
		deal(a+len,b,a+len,b+len-1,len);
		deal(a+len,b+len,x,y,len);
	}
}
int main()
{
	int m;
	int x,y;
	scanf("%d %d %d",&m,&x,&y); 
	m=1<<m;
	deal(1,1,x,y,m);
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值