有一个有2^k×2^k个方格的棋盘,恰有一个方格是黑色的,其他为白色。你的任务是用包含3个方格的L型牌覆盖所有白色方格。黑色方格不能被覆盖,且任意一个白色方格不能同时被两个或更多牌覆盖。如图(1)所示为L型牌的四种旋转方式。
下图–图(1)中的特殊棋盘是当k=3时16个特殊棋盘中的一个:
图(1)
输入格式:
第一行含有三个数据:分别为n(<=50 <=0 保证是4的倍数):棋盘边长,x(<=n >=1):特殊方格横坐标,y(<=n >=1):特殊方格纵坐标。
输入样例:
8 5 6
输出样例:
4 4 5 5 9 9 10 10
4 2 2 5 9 7 7 10
6 2 0 3 8 8 7 11
6 6 3 3 1 8 11 11
14 14 13 1 1 18 19 19
14 12 13 13 18 18 17 19
15 12 12 16 20 17 17 21
15 15 16 16 20 20 21 21
本题解题思路:
图为样例输入
先将棋盘分割成四个子棋盘,再将没有特殊方格的子棋盘的靠近分割点的三格覆盖骨牌。
将子棋盘再分割成四个更小的子棋盘,并按照之前的方法,将黄色格子当做特殊格子,实现分治,将没有特殊方格的子棋盘的靠近中心分割点的三格覆盖骨牌。
子棋盘为2×2时填充剩下的格子便完成了。
代码如下:
#include<cstdio>
using namespace std;
int x,y,n,i,j,t=0;
//x:特殊格子横坐标 y:特殊格子纵坐标 n:棋盘边长 i,j:循环变量 t:当前骨牌编号
int map[51][51];
//本程序使用递归实现分治.
void CB(int x,int y,int m,int n,int s)
//x:棋盘左上角横坐标 y:棋盘左上角纵坐标 m:特殊格子横坐标 n:特殊格子纵坐标 s:棋盘边长
{
int sa,temp;//sa:子棋盘边长 temp:交换临时变量
if(s==2)//递归边界:子棋盘边长=2
{
temp=map[m][n];//先将四个格子全部覆盖,再将原来的特殊格子重新填充
map[x][y]=t+1;
map[x][y+1]=t+1;
map[x+1][y]=t+1;
map[x+1][y+1]=t+1;
map[m][n]=temp;
t++;
return;
}
t++;
sa=s/2;
if(m<x+sa && n<y+sa) //特殊格子在左上角
{
map[x+sa-1][y+sa]=t;//摆放骨牌
map[x+sa][y+sa-1]=t;
map[x+sa][y+sa]=t;
CB(x,y,m,n,sa);//递归调用子棋盘
CB(x,y+sa,x+sa-1,y+sa,sa);
CB(x+sa,y,x+sa,y+sa-1,sa);
CB(x+sa,y+sa,x+sa,y+sa,sa);
}
if(m<x+sa && n>=y+sa) //特殊格子在右上角
{
map[x+sa-1][y+sa-1]=t;//摆放骨牌
map[x+sa][y+sa-1]=t;
map[x+sa][y+sa]=t;
CB(x,y+sa,m,n,sa);//递归调用子棋盘
CB(x,y,x+sa-1,y+sa-1,sa);
CB(x+sa,y,x+sa,y+sa-1,sa);
CB(x+sa,y+sa,x+sa,y+sa,sa);
}
if(m>=x+sa && n<y+sa) //特殊格子在左下角
{
map[x+sa-1][y+sa-1]=t;//摆放骨牌
map[x+sa-1][y+sa]=t;
map[x+sa][y+sa]=t;
CB(x+sa,y,m,n,sa);//递归调用子棋盘
CB(x,y,x+sa-1,y+sa-1,sa);
CB(x,y+sa,x+sa-1,y+sa,sa);
CB(x+sa,y+sa,x+sa,y+sa,sa);
}
if(m>=x+sa && n>=y+sa) //特殊格子在右下角
{
map[x+sa-1][y+sa-1]=t;//摆放骨牌
map[x+sa-1][y+sa]=t;
map[x+sa][y+sa-1]=t;
CB(x+sa,y+sa,m,n,sa);//递归调用子棋盘
CB(x,y,x+sa-1,y+sa-1,sa);
CB(x,y+sa,x+sa-1,y+sa,sa);
CB(x+sa,y,x+sa,y+sa-1,sa);
}
}
int main()
{
scanf("%d%d%d",&n,&x,&y);//n:棋盘边长 x:特殊格子横坐标 y:特殊格子纵坐标
CB(1,1,x,y,n);//调用递归
for(i=1;i<=n;i++)//循环输出结果
{
for(j=1;j<=n;j++) printf("%3d",map[i][j]);
printf("\n");
}
return 0;
}