棋盘覆盖问题
什么是棋盘覆盖问题
关于这个,百度一下,你就知道,本文主要介绍棋盘覆盖问题的思路
求解思路
- 对于一个给定的
2
k
∗
2
k
2^{k}*2^{k}
2k∗2k的特殊棋盘,假设其特殊方格(蓝色部分)如下图所示。
若再在中央位置放入一个L形骨牌,则将其由中央十字分出的四个部分子棋盘(A、B、C、D),变成了特殊棋盘(如下图),其被分为了4个特殊棋盘
欲将其如此分为四个特殊棋盘,该L型骨牌的形状需要满足:对于该L型骨牌所在的三块方格(可视为特殊方格),每个方格所在的子棋盘没有任何其它特殊方格,以这样的方式在中央放入L形骨牌,则可将一个特殊棋盘划分为4个子特殊棋盘,如此对每个子特殊棋盘进行同样的划分操作,依次递归,在棋盘只有一个方块时直接返回。如此,用L型骨牌覆盖了整个棋盘。
代码
#include <iostream>
#include <string.h>
using namespace std;
typedef long long ll;
ll pansize,xa,ya; //棋盘边长,特殊方格的位置坐标
ll qipan[10000][10000];
ll num=0;//已放入L形骨牌的数量
// stx,sty:棋盘最左上角方格坐标、xa,ya:特殊方格坐标
void Cover(ll stx,ll sty,ll pansize,ll xa,ll ya)
{
if(pansize==1)
{
return;
}
ll len=pansize/2;// 子棋盘的宽度
++num;//在中央放入L形骨牌,分解为四个特殊子棋盘
if(xa<stx+len&&ya<sty+len)
{
qipan[stx+len][sty+len-1]=num;
qipan[stx+len][sty+len]=num;
qipan[stx+len-1][sty+len]=num;
Cover(stx,sty,len,xa,ya);
Cover(stx+len,sty,len,stx+len,sty+len-1);
Cover(stx+len,sty+len,len,stx+len,sty+len);
Cover(stx,sty+len,len,stx+len-1,sty+len);
}
if(xa>=stx+len&&ya<sty+len)
{
qipan[stx+len-1][sty+len-1]=num;
qipan[stx+len-1][sty+len]=num;
qipan[stx+len][sty+len]=num;
Cover(stx,sty,len,stx+len-1,sty+len-1);
Cover(stx+len,sty,len,xa,ya);
Cover(stx+len,sty+len,len,stx+len,sty+len);
Cover(stx,sty+len,len,stx+len-1,sty+len);
}
if(xa>=stx+len&&ya>=sty+len)
{
qipan[stx+len-1][sty+len-1]=num;
qipan[stx+len][sty+len-1]=num;
qipan[stx+len-1][sty+len]=num;
Cover(stx,sty,len,stx+len-1,sty+len-1);
Cover(stx+len,sty,len,stx+len,sty+len-1);
Cover(stx+len,sty+len,len,xa,ya);
Cover(stx,sty+len,len,stx+len-1,sty+len);
}
if(xa<stx+len&&ya>=sty+len)
{
qipan[stx+len-1][sty+len-1]=num;
qipan[stx+len][sty+len-1]=num;
qipan[stx+len][sty+len]=num;
Cover(stx,sty,len,stx+len-1,sty+len-1);
Cover(stx+len,sty,len,stx+len,sty+len-1);
Cover(stx+len,sty+len,len,stx+len,sty+len);
Cover(stx,sty+len,len,xa,ya);
}
}
int main()
{
memset(qipan,0,10000*10000*sizeof(ll));
printf("棋盘边长:");
scanf("%lld",&pansize);
printf("特殊方格位置:");//坐标从0开始
scanf("%lld%lld",&xa,&ya);
printf("覆盖结果:\n");
Cover(0,0,pansize,xa,ya);
for(ll i1=0;i1<pansize;++i1)
{
for(ll i2=0;i2<pansize;++i2)
{
if(i2!=pansize-1)
{
printf("%lld ",qipan[i1][i2]);
}
else
{
printf("%lld\n",qipan[i1][i2]);
}
}
}
return 0;
}