一开始题目都没读懂。。。
其实就是一个递归分治,每次递归寻找特殊数,划分为四块,如果当前块中没有特殊数,我们则构造特殊数。
题目
任务描述
在一个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;
}