题目
问题分析
这个题目就是当前图以上一个图为基准单元输出麻将中五饼的形状,递推公式已经给出,用递归实现即可。
算法
算法核心
本题采用分治算法,求解问题先得到子问题的解,就是要画出第n个图,先画出第n-1个图,要画第n-1个图先画第n-2个图,在分解到上一级图的时候按照坐标分解,直至分解到最小子问题也就是只有一个X为止,将结果储存在数组中,最后遍历输出数组即可。
算法流程
首先初始化结果数组,然后将参数传入递归函数Fractal(int x,int y,n),其中x为行数,y为列数,n为第几个图,如果n==1,那么已分解到最小子问题,a[x][y]=‘X’;如果n!=1,那么还要继续分解,由样例可知每个图(n>=2时)的基准单元长和宽都是3^(n-2), 所以就分五个部分,再调用Fractal()函数,以中间单元为例,m=3^(n-2);Fractal(x+m,y+m,n-1);最后遍历输出即可。在输出的时候可以直接双重遍历,也可以先把每一行的最后一位置为’\0’,然后按行数遍历,输出字符串。
代码实现
#include<iostream>
using namespace std;
const int maxn=1005;
char a[maxn][maxn];
int n,m;
int thr(int x)//求3^x
{
int sum=1;
for(int i=0; i<x; ++i)
sum*=3;
return sum;
}
void fractal(int x,int y,int n)
{
if(n==1)
{
a[x][y]='X';
return ;
}
else
{
int d=thr(n-2);
fractal(x,y,n-1);
fractal(x,y+2*d,n-1);
fractal(x+d,y+d,n-1);
fractal(x+2*d,y,n-1);
fractal(x+2*d,y+2*d,n-1);
}
}
void output()
{
int i,j;
m=thr(n-1);
for(i=0; i<m; ++i)//双重循环直接遍历输出
{
for(j=0; j<m; ++j)
cout<<a[i][j];
cout<<endl;
}
cout<<"-"<<endl;
}
int main()
{
int i,j;
while(cin>>n&&n!=-1)
{
for(i=0; i<maxn; ++i)
for(j=0; j<maxn; ++j)
a[i][j]=' ';
fractal(0,0,n);
output();
}
return 0;
}
输出函数也可以这样写
void output()
{
int i,j;
m=thr(n-1);
for(i=0; i<m; ++i)
for(j=m; j>=0; --j)
if(a[i][j]=='X')
{
a[i][j+1]='\0';//把每一行都变成字符串
break;
}
for(i=0; i<m; ++i)//逐行输出
cout<<a[i]<<endl;
cout<<"-"<<endl;
}