0
点赞
收藏
分享

微信扫一扫

棋盘覆盖问题

陆公子521 2022-03-25 阅读 77
算法c++

题目

在一个 2 k × 2 k 2^{k}\times 2^{k} 2k×2k个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
特殊骨牌的牌号为0
正常骨牌号从1开始
覆盖棋盘请严格遵循先覆盖左上角,右上角,左下角,右下脚的循序

输入样例:

3 3 2

输出样例:

3   3   4   4   8   8   9   9
3   2   2   4   8   7   7   9
5   2   6   6   10  10  7   11
5   5   0   6   1   10  11  11
13  13  14  1   1   18  19  19
13  12  14  14  18  18  17  19
15  12  12  16  20  17  17  21
15  15  16  16  20  20  21  21

思路

采用分治的方法。

代码

#include<stdio.h>
int k, x, y;
int p[1025][1025];
int d[4][6] = {{0,1,1,1,0,1},{0,1,1,-1,-1,0},{-1,-1,0,0,1,1},{-1,-1,0,-1,0,-1}};
int dt[4][2] = {{0,0},{0,1},{1,0},{1,1}};
struct node
{
	int x, y;
	node(int x_, int y_){
		x = x_, y = y_;
	};
	node(){};
};
int cnt;
int binpow(int a, int b){
	int res = 1;
	while(b){
		res *= a;
		b--;
	}
	return res;
}
void pri(){
	for(int i = 0;i < binpow(2,k);i++){
		for(int j = 0;j < binpow(2,k);j++){
			if(j < binpow(2,k)-1)printf("%-4d",p[i][j]);
			else printf("%d",p[i][j]);
		}
		printf("\n");
	}
}
int check(int ltx, int lty, int a, int b, int l){
	int len = binpow(2,l-1);
	if(a < ltx + len&&b < lty + len)return 0;
	else if(a < ltx + len&&b >= lty + len)return 1;
	else if(a >= ltx + len&&b < lty + len)return 2;
	return 3;
}
void dfs(int ltx, int lty, int a, int b, int l){
	if(binpow(2,l) < 2)return ;
	int vis = check(ltx,lty,a,b,l);
	node idx[4];
	idx[vis] = {a,b};
	int ta = ltx + binpow(2,l-1)-1;
	int tb = lty + binpow(2,l-1)-1;
	ta += dt[vis][0];tb += dt[vis][1];
	cnt++;
	int vim = 0;
	for(int i = 0;i < 3;i++){
		if(vim==vis){
			vim++;
		}
		int c = ta + d[vis][i];
		int r = tb + d[vis][i+3];
		idx[vim++] = {c,r};
		p[c][r] = cnt;
	}
	for(int i = 0;i < 4;i++){
		dfs(ltx+binpow(2,l-1)*dt[i][0],lty+binpow(2,l-1)*dt[i][1],idx[i].x,idx[i].y,l-1);
	}
}
int main(){
	scanf("%d%d%d",&k,&x,&y);
	dfs(0,0,x,y,k);
	pri();
}
举报

相关推荐

0 条评论