Tromino 棋盘覆盖谜题 分治求解

给一个 2 n 2^n 2n * 2 n 2^n 2n 的棋盘。

每次把棋盘划分成4个部分,每个部分都是 2 n − 1 2^{n-1} 2n1 * 2 n − 1 2^{n-1} 2n1 把有黑色点的区域继续递归下去,
剩下的3个区域,各自把靠两条分割线最近的一个点染黑,形成一个L的样子。
例如 在这里插入图片描述

递归下去直到n = 1 会发现刚好有一个已经染色,剩下3个形成一个L.

测试代码:

#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 999911659;
const int N = 210;

/*
	棋盘覆盖问题。
	x,y 表示黑点位置,sax,say表示子区域左上角坐标,
	siz表示区域大小为siz*siz,k表示第几次 
	每次分成4个子区域,除了有黑点的子区域,其它在靠近中心的地方标黑 
*/

int mp[N][N];
void chessboard(int x,int y,int sax,int say,int siz,int k){
	if(siz == 2){
		for(int i=sax;i<sax+2;i++)
			for(int j=say;j<say+2;j++)
				if(!mp[i][j]) mp[i][j] = k;
		return ;
	}
	int tx = x,ty = y;
	siz /= 2;
	// 左上,右上,左下,右下。 
	if(x >= sax+siz || y >= say+siz) mp[sax+siz-1][say+siz-1] = k,tx=sax+siz-1,ty=say+siz-1;
	chessboard(tx,ty,sax,say,siz,k+1);
	tx = x,ty = y;
	if(x < sax+siz || y >= say+siz) mp[sax+siz][say+siz-1] = k,tx=sax+siz-1,ty=say+siz-1;
	chessboard(tx,ty,sax+siz,say,siz,k+1);
	tx = x,ty = y;
	if(x >= sax+siz || y < say+siz) mp[sax+siz-1][say+siz] = k,tx=sax+siz-1,ty=say+siz-1;
	chessboard(tx,ty,sax,say+siz,siz,k+1);
	tx = x,ty = y;
	if(x < sax+siz || y < say+siz) mp[sax+siz][say+siz] = k,tx=sax+siz-1,ty=say+siz-1;
	chessboard(tx,ty,sax+siz,say+siz,siz,k+1);
}

signed main(){
//	IOS;
	#ifdef ddgo
		freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
	#endif
	
	int si,x,y; cin>>si>>x>>y;
	mp[x][y] = 9;//特殊标记一下黑点
	chessboard(x,y,0,0,si,1);
	
	for(int i=0;i<si;i++){
		for(int j=0;j<si;j++)
			cout<<mp[i][j]<<" "; 
		cout<<endl;
	}
	
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值