#include <iostream>
using namespace std;
/*
*这个题的主要思想:
*1、平均吧这个2的k次幂的方格划分为4个部分
*2、一个含有特殊方格的为一部分
*3、剩下3个没有特殊方格的分别贡献一个小方块合成一个“L”
*4、然后把刚刚贡献出去的小方格当成一个特殊方格,重新回到步骤1
*5、如果特殊方格不足4个的时候就是已经全部分完了,跳出去
*/
//我们得知道是k行k列的方格,所以会有k,知道特殊方格的位置行和列 th, tl,划分后的新的方格的起始位置newh,newl,行和列
void qiPan(int k, int th, int tl, int newh, int newl, int a[])
{
//开始分割棋盘,划分为4个部分
if(k == 1) //只有一个特殊方格占据全部
return; //用到0个L型的骨牌
/*
骨牌可以有4种
-----------------------------------
** ** * *
* * ** **
------------------------------------
*/
int t=0; //骨牌的编号
int s=k/2; //分割棋盘
// int a[4] = {0}; //代表四种不同的L型的方格
//在开始的划分为4个部分的时候,特殊方格可以存在4个大块里的每一块
//特殊方格在左上部分
if(th < newh+s && tl < newl+s)
{
//这里特殊方格是在左上方的话,就调用4号L骨牌
a[3]+=1;
qiPan(s, th, tl, newh, newl, a); //s:这个是分割棋盘的行数 th:特殊方格的高 tl:特殊方格的列 newh:这个大的方格的起始行 newl:起始列
}
else
{//左上片棋盘中没有特殊方格的话
//那就把左下角那个方格作为L的一部分用L挡住
qiPan(s, newh+s-1, newl+s-1, newh, newl, a);
}
//------------------------------------------------------------------------------------
//特殊方格在左下部分
if(th > newh+s-1 && tl < newl+s)
{
//这里特殊方格是在左上方的话,就调用2号L骨牌
a[1]++;
qiPan(s, th, tl, newh+s, newl, a); //s:这个是分割棋盘的行数 th:特殊方格的高 tl:特殊方格的列 newh:这个大的方格的起始行 newl:起始列
}
else
{//左上片棋盘中没有特殊方格的话
//那就把左下角那个方格作为L的一部分用L挡住
qiPan(s, newh + s, newl + s - 1, newh+s, newl, a);
}
//------------------------------------------------------------------------------------
/*
骨牌可以有4种
-----------------------------------
** ** * *
* * ** **
------------------------------------
*/
//特殊方格在右上部分
if(th < newh+s && tl > newl+s-1)
{
//这里特殊方格是在左上方的话,就调用3号L骨牌
a[2]++;
qiPan(s, th, tl, newh, newl+s, a); //s:这个是分割棋盘的行数 th:特殊方格的高 tl:特殊方格的列 newh:这个大的方格的起始行 newl:起始列
}
else
{//左上片棋盘中没有特殊方格的话
//那就把左下角那个方格作为L的一部分用L挡住
qiPan(s, newh + s - 1, newl + s, newh, newl+s, a);
}
//------------------------------------------------------------------------------------
//特殊方格在右下部分
if(th > newh+s-1 && tl > newl+s-1)
{
//这里特殊方格是在左上方的话,就调用1号L骨牌
a[0]++;
qiPan(s, th, tl, newh+s, newl + s, a); //s:这个是分割棋盘的行数 th:特殊方格的高 tl:特殊方格的列 newh:这个大的方格的起始行 newl:起始列
}
else
{//左上片棋盘中没有特殊方格的话
//那就把左下角那个方格作为L的一部分用L挡住
qiPan(s, newh + s, newl + s, newh+s, newl+s, a);
}
}
/*
void test(int *b)
{
for (int i = 0; i <= 3; ++i)
{
b[i]++;
if (i == 2)
{
b[i] = 998;
}
}
}
*/
int main()
{
char c;
int a[4] = { 0 };
qiPan(4, 1, 2, 1, 1, a);
//cout << "一共:" << qiPan(4, 1, 2, 1, 1, a) <<"个"<< endl;
/*
骨牌可以有4种
-----------------------------------
** ** * *
* * ** **
------------------------------------
*/
char L[4][2][2] = //使用一个多维数组来表示这几个L型的骨牌
{
{ { '*', '*' }, { '*', ' ' } },
{ { '*', '*' }, { ' ', '*' } },
{ { '*', ' ' }, { '*', '*' } },
{ { ' ', '*' }, { '*', '*' } }
};
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 2; ++j) //第i个骨牌的第一行
{
for (int k = 0; k < 2; ++k) //每行的情况
{
cout << L[i][j][k];
}
cout << endl;
}
cout << "第 " << i +1 << " 个L型的骨牌的使用次数是:" << a[i] << endl;
}
/*
test(a);
for (int i = 0; i < 4; ++i)
{
cout << a[i] << endl;
}
*/
cin >> c;
return 0;
}
【算法设计与分析】2、棋盘覆盖问题
最新推荐文章于 2024-01-04 17:17:23 发布