L型组件填图问题
1.问题描述
设B是一个n×n棋盘,n=2k,(k=1,2,3,…)。用分治法设计一个算法,使得:用若干个L型条块可以覆盖住B的除一个特殊方格外的所有方格。其中,一个L型条块可以覆盖3个方格。且任意两个L型条块不能重叠覆盖棋盘。
例如:如果n=2,则存在4个方格,其中,除一个方格外,其余3个方格可被一L型条块覆盖;当n=4时,则存在16个方格,其中,除一个方格外,其余15个方格被5个L型条块覆盖。
2. 具体要求
输入一个正整数n,表示棋盘的大小是n*n的。输出一个被L型条块覆盖的n*n棋盘。该棋盘除一个方格外,其余各方格都被L型条块覆盖住。为区别出各个方格是被哪个L型条块所覆盖,每个L型条块用不同的数字或颜色、标记表示。
3. 测试数据
输入:8
输出:
4. 设计与实现的提示
对2k×2k的棋盘可以划分成若干块,每块棋盘是原棋盘的子棋盘或者可以转化成原棋盘的子棋盘。
注意:特殊方格的位置是任意的。而且,L型条块是可以旋转放置的。为了区分出棋盘上的方格被不同的L型条块所覆盖,每个L型条块可以用不同的数字、颜色等来标记区分。
可以采用可视化界面用不同颜色来表示各L型条块,显示其覆盖棋盘的情况。输出有多种表示方式。
code:
#include <iostream>
using namespace std;
void L_Suanfa(int *qipan, int n, int num)
{
if (n==2)
{
qipan[0*num + 1] = 1;
qipan[1*num + 1] = 1;
qipan[1*num + 0] = 1;
return;
}
L_Suanfa(qipan,n/2, num);
int b = n;
for (int i=0; i<n/2; i++)
{
for (int j=0; j<n/2; j++)
{
int a = qipan[i*num + j];
if (a != 0)
{
qipan[(n/2+i)*num + n/2+j] = qipan[i*num + j]+ b*b;//n/2/2+b;
qipan[(n/2-i-1)*num + n/2+j] = qipan[(n/2+i)*num + n/2+j] +b*b;
qipan[(n/2+i)*num + n/2-j-1] = qipan[(n/2+i)*num + n/2+j] +b*b*b;
}
}
}
qipan[(n/2-1)*num + n/2] = qipan[(n/2+1)*num + n/2-1] +b*b;//b +1;//50+b;
qipan[(n/2)*num + n/2] = qipan[(n/2)*num + n/2-1] = qipan[(n/2+1)*num + n/2-1] +b*b;//+ 1;
}
void Output(int *qipan, int n)
{
cout<<endl;
for (int i=0; i<n; i++)
{
for (int j=0;j<n; j++)
{
//cout<<qipan[i*n + j]<<" ";
printf("%3d ", qipan[i*n + j]);
}
cout<<endl;
}
}
int main()
{
int n;
cout<<"send in n=";
cin>>n;
while (n!=0)
{
int *qipan = new int[n*n];
memset(qipan,0,sizeof(int)*n*n);
L_Suanfa(qipan, n, n);
Output(qipan,n);
delete qipan;
cout<<"send in n=";
cin>>n;
}
cin.get();
return 0;
}