前言
个人小记
一、棋盘覆盖问题是什么?
假设有一个 2 n × 2 n 2^n \times 2^n 2n×2n 的棋盘,其中一个方格被移除(比如说是一个角落的方格)。现在有 L 形的骨牌,每个骨牌覆盖 3 个方格,要求用这些 L 形骨牌覆盖整个棋盘,且不能有重叠
二、代码
#include<stdio.h>
#include <stdlib.h>
int **init_board(int k)
{
int **board=(int**)malloc(sizeof(int *)*k);
for(int i=0;i<k;i++)
{
board[i]=(int *)malloc(sizeof(int)*k);
}
for(int i=0;i<k;i++)
{
for(int j=0;j<k;j++)
{
board[i][j]=0;
}
}
return board;
}
int f=1;
void converboard(int sr,int sc,int dr,int dc,int size,int **board)
{
if(size==1)return ;
size/=2;
int flg=f++;
if(dr<sr+size&&dc<sc+size)converboard(sr,sc,dr,dc,size,board);
else
{
board[sr+size-1][sc+size-1]=flg;
converboard(sr,sc,sr+size-1,sc+size-1,size,board);
}
if(dr<sr+size&&dc>=sc+size)converboard(sr,sc+size,dr,dc,size,board);
else
{
board[sr+size-1][sc+size]=flg;
converboard(sr,sc+size,sr+size-1,sc+size,size,board);
}
if(dr>=sr+size&&dc<sc+size)converboard(sr+size,sc,dr,dc,size,board);
else
{
board[sr+size][sc+size-1]=flg;
converboard(sr+size,sc,sr+size,sc+size-1,size,board);
}
if(dr>=sr+size&&dc>=sc+size)converboard(sr+size,sc+size,dr,dc,size,board);
else
{
board[sr+size][sc+size]=flg;
converboard(sr+size,sc+size,sr+size,sc+size,size,board);
}
return ;
}
void clear(int **board,int k)
{
if(board==NULL)return ;
for(int i=0;i<k;i++)
{
free(board[i]);
}
free(board);
return ;
}
int main()
{
int x,y,k;
printf("请输入特殊棋盘的行大小2^k中的k:");
scanf("%d",&k);
k=1<<k;
int **board=init_board(k);
printf("请输入特殊方格的位置x y:");
scanf("%d%d",&x,&y);
board[x][y]=-1;
converboard(0,0,x,y,k,board);
for(int i=0;i<k;i++)
{
for(int j=0;j<k;j++)
{
printf("%3d",board[i][j]);
}
printf("\n");
}
clear(board,k);
return 0;
}
三、运行结果
请输入特殊棋盘的行大小2^k中的k:3
请输入特殊方格的位置x y:2 2
3 3 4 4 8 8 9 9
3 2 2 4 8 7 7 9
5 2 -1 6 10 10 7 11
5 5 6 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