一. 问题的提出:
在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
二. 解决思路
确定特殊棋盘的方位,如左上,左下,右上,右下。再将其他棋盘转化为特殊棋盘,转化方法具体如图。递归调用。
主要思想为分治。
(图片来源:和讯博客,Anita的博客,在此感谢。)
三:源代码
//该代码以相同的数字作为“L”型格
// Qi Pan.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
int q=1;
void FillChessBroad(int **A,int Size,int x,int y,int a,int b);
void main()
{
using namespace std;
int x,y,Size,**A,t,a=1,b=1;
cout<<"请输入棋盘边长大小(大小为2的K次方):";
cin>>Size;
cout<<"请输入坏点坐标:";
cin>>x>>y;
//声明一个动态二维数组作为棋盘,其大小为Size*Size
A=new int *[Size];
for(t=0;t<Size;t++)
{
A[t]=new int[Size];
}
A[x-1][y-1]=0;//将坏点的值设为0,以便区别于填充的部分。
FillChessBroad(A,Size,x,y,a,b);
for(x=0;x<Size;x++)//打印覆盖后的棋盘
{
for(y=0;y<Size;y++)
printf("%d",A[x][y]);
printf("/n");
}
getchar();
getchar();
return;
}
void FillChessBroad(int **A,int Size,int x,int y,int a,int b)
{
if(Size==1)
return;
q==9?q=1:q=q++;//以相同的数字表示“L”型格,便于画图。
/*****处理左上角*****/
if(x<a+Size/2&&y<b+Size/2)//如果坏点在左上角。
{
A[a+Size/2-1][b+Size/2-1]=q;//对角
A[Size/2+a-2][Size/2+b-1]=q;//下方
A[Size/2+a-1][Size/2+b-2]=q;//右方
FillChessBroad(A,Size/2,Size/2+a,Size/2+b,Size/2+a,Size/2+b);//递归
FillChessBroad(A,Size/2,Size/2+a-1,Size/2+b,a,Size/2+b);
FillChessBroad(A,Size/2,Size/2+a,Size/2+b,Size/2+a,b);
FillChessBroad(A,Size/2,x,y,a,b);
}
/*****处理右上角*****/
if(x>=Size/2+a&&y<Size/2+b)//如果坏点在右上角。
{
A[Size/2+a-2][Size/2+b-1]=q;//对角
A[Size/2+a-1][Size/2+b-1]=q;//下方
A[Size/2+a-2][Size/2+b-2]=q;//左方
FillChessBroad(A,Size/2,Size/2+a-1,Size/2+b,a,Size/2+b);
FillChessBroad(A,Size/2,Size/2+a,Size/2+b,Size/2+a,Size/2+b);
FillChessBroad(A,Size/2,Size/2+a-1,Size/2+b-1,a,b);
FillChessBroad(A,Size/2,x,y,a+Size/2,b);
}
/*****处理左下角*****/
if(x<Size/2+a&&y>=Size/2+b)//如果坏点在左下角。
{
A[Size/2+a-1][Size/2+b-2]=q;//对角
A[Size/2+a-2][Size/2+b-2]=q;//上方
A[Size/2+a-1][Size/2+b-1]=q;//右方
FillChessBroad(A,Size/2,Size/2+a,Size/2+b-1,Size/2+a,b);
FillChessBroad(A,Size/2,Size/2+a-1,Size/2+b-1,a,b);
FillChessBroad(A,Size/2,Size/2+a,Size/2+b,Size/2+a,Size/2+b);
FillChessBroad(A,Size/2,x,y,a,b+Size/2);
}
/*****处理右下角*****/
if(x>=Size/2+a&&y>=Size/2+b)//如果坏点在右上角。
{
A[Size/2+a-2][Size/2+b-2]=q;//对角
A[Size/2+a-1][Size/2+b-2]=q;//上方
A[Size/2+a-2][Size/2+b-1]=q;//左方
FillChessBroad(A,Size/2,Size/2+a-1,Size/2+b-1,a,b);
FillChessBroad(A,Size/2,Size/2+a,Size/2+b-1,Size/2+a,b);
FillChessBroad(A,Size/2,Size/2+a-1,Size/2+b,a,Size/2+b);
FillChessBroad(A,Size/2,x,y,a+Size/2,b+Size/2);
}
}