残缺棋盘问题
对于1*1 2*2 4*4 8*8等 2^k*2^k的棋盘来说,都存在一个任意的位置,而在棋盘剩余位置都可以用一个或多个由三个格子组成的L型直角版覆盖
那么如何覆盖呢?
在这里 采用分而治之的方法来考虑。
对于已知的残缺位置,一定处于当前棋盘的某个象限,那么在剩下的三个象限中在连接的地方各取一个方块为残缺,这三个方块的位置刚好可以构成
一个L型直角,而对于每个象限而言又是规定了一个残缺位置,这样与初始状态又一致了。也就是说,将一个完整的棋盘不断地化为四份,并
且补充每个象限中的残缺位置,直到不能再划分。利用递归来实现。
代码如下:
#include<iostream>
#include<string>
#include<stdlib.h>
#include <iomanip>
using namespace std;
//递归实现残缺棋盘
int tag = 0;
void function(int tr, int tc, int dr, int dc, int size,int **target);// (tr,tc)表示该棋盘的最左上角的方格的坐标。 (dr,dc)表示残缺方格的位置坐标 size表示棋盘的行列数 target是用来
//存放L型直角编码的。 位置从(0,0)开始计算
int main()
{
int size =16;
int **target = new int*[size];
//把相应的二维数组初始化 全都初始化为0
for (int i = 0; i < size; i++)
{
target[i] = new int[size];
for (int j = 0; j < size; j++)
target[i][j] = 0;
}
function(0, 0, 3, 3, size, target);
//输出这个数组
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
cout <<setw(2)<< target[i][j] << " ";
}
cout << endl;
}
system("pause");
//删除这个二维数组
for (int i = 0; i < size; i++)
{
delete[] target[i];
}
delete[] target;
target = 0;
return 0;
}
void function(int tr, int tc, int dr, int dc, int size,int **target)
{
int s = size / 2;
int t = ++tag;
if (s == 0)
return;//当size==1时不再继续递归,返回上一层。
//讨论缺陷在左上角的情况
if ((tr+s) > dr && (tc+s) > dc)
{
//本身所在的小棋盘保持不变
function(tr, tc, dr, dc, s, target);
//将右上角的棋盘的左下角的格子置为缺陷,并且用t来标记
target[tr + s - 1][tc + s] = t;
function(tr, tc + s, tr + s - 1, tc + s, s, target);
//将左下角棋盘的右上角的格子置为缺陷,并且标记。
target[tr + s][tc + s - 1] = t;
function(tr + s, tc, tr + s, tr + s - 1, s, target);
//将右下角棋盘的左上角的格子置为缺陷,并且标记
target[tr + s][tc + s] = t;
function(tr + s, tc + s, tr + s, tc + s, s, target);
}
//讨论缺陷在右上角的情况 与第一种情况相似 模仿着来写
//void function(int tr, int tc, int dr, int dc, int size,int **target)
else if ((tr+s) > dr &&(tc+s) <= dc)
{
target[tr + s - 1][tc + s - 1] = t;
function(tr, tc, tr + s - 1, tr + s - 1, s, target);
function(tr, tc + s, dr, dc, s, target);
target[tr + s][tc + s - 1] = t;
function(tr + s, tc, tr + s, tc + s - 1, s, target);
target[tr + s][tc + s] = t;
function(tr + s, tc + s, tr + s, tc + s, s, target);
}
//缺陷在左下角的情况
else if ((tr+s) <= dr &&(tc+s) > dc)
{
target[tr+s-1][tc+s-1] = t;
function(tr, tc, tr + s - 1, tc + s - 1, s, target);
target[tr+s-1][tc+s] = t;
function(tr, tc + s, tr + s - 1, tc + s, s, target);
function(tr + s, tc, dr, dc, s, target);
target[tr+s][tc+s] = t;
function(tr + s, tc + s, tr + s, tc + s, s, target);
}
//缺陷在右下角的时候
else
{
target[tr + s - 1][tc + s - 1] = t;
function(tr, tc, tr + s - 1, tc + s - 1, s, target);
target[tr + s - 1][tc + s] = t;
function(tr, tc + s, tr + s - 1, tc + s, s, target);
target[tr + s][tc + s - 1] = t;
function(tr + s, tc, tr + s, tc + s - 1, s, target);
function(tr + s, tc + s, dr, dc, s, target);
}
}