题目
在一个
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();
}