棋盘覆盖问题(递归分治)

一开始题目都没读懂。。。
其实就是一个递归分治,每次递归寻找特殊数,划分为四块,如果当前块中没有特殊数,我们则构造特殊数。

题目

任务描述
在一个2k×2k个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
易知,覆盖任意一个2k×2k的特殊棋盘,用到的骨牌数恰好为(4K-1)/3。

输入格式
第一行为k(棋盘的尺寸),第二行为x,y(1<=x,y<=2^k),分别表示特殊方格所在行与列。

输出格式
共2^k行,分别表示覆盖该格的L型的编号(特殊格用0表示)。

输出要求:最小字符宽度为4,左对齐输出

测试输入:
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

提示:
特殊骨牌的牌号为0
正常骨牌号从1开始
覆盖棋盘请严格遵循先覆盖左上角,右上角,左下角,右下脚

题解

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

#include<stdio.h>

int k=1;
int a[1086][1086];

void solve(int lx,int ly,int spex,int spey,int len){
    
    
	if(len<=1) return;
	int t=k++;
	len=len/2;
	
	//左上 
	if(spex<lx+len&&spey<ly+len) solve(lx,ly,spex,spey,len);
	else a[lx+len-1][ly+len-1]=t,solve(lx,ly,lx+len-1,ly+len-1,len);
	
	//右上 
	if(spex<lx+len&&spey>=ly+len)
	  solve(lx,ly+len,spex,spey,len);
	else  a[lx+len-1][ly+len]=t,solve(lx,ly+len,lx+len-1,ly+len,len);
	
	//左下
	if(spex>=lx+len&&spey<ly+len)
	  solve(lx+len,ly,spex,spey,len);
	else
	  a[lx+len][ly+len-1]=t,solve(lx+len,ly,lx+len,ly+len-1,len);
	
	//右下
	if(spex>=lx+len&&spey>=ly+len)
	  solve(lx+len,ly+len,spex,spey,len);
	else
	  a[lx+len][ly+len]=t,solve(lx+len,ly+len,lx+len,ly+len,len); 

}
int main(){
    
    
	int n,x,y;
	scanf("%d%d%d",&n,&x,&y);
	n=1<<n;
	//cout<<n<<endl;
	solve(0,0,x,y,n);
	for(int i=0;i<n;i++){
    
    
	  for(int j=0;j<n;j++){
    
    
        if(j!=n-1) printf("%-4d",a[i][j]);
        else printf("%d",a[i][j]);
	  }
	  printf("\n");
}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jigsaw_zyx/article/details/123567302