题目链接
题目描述
题目描述
给定一个正整数 n,参考输出样例,输出图形。
输入格式
每个数据输入一个正整数 n,表示图腾的大小(此大小非彼大小)
输出格式
这个大小的图腾
输入输出样例
输入1
2
输出1
/\ /__\ /\ /\ /__\/__\
输入2
3
输出2
/\ /__\ /\ /\ /__\/__\ /\ /\ /__\ /__\ /\ /\ /\ /\ /__\/__\/__\/__\
说明/提示
数据保证,1 ≤ n ≤ 10。
思路分析
这道题采用分冶法
分冶法定义
分冶法是把一个规模为N的问题分成两个或多个较小的与原问题类型相同的子问题,通过对子问题的求解,并把子问题的解合并起来从而构成整个问题的解,即对问题各个击破,分而治之。如果子问题的的规模仍然相当大,仍不足以很容易的求得它的解,这时可以对此子问题重复的应用分冶策略。
思路分析
细心观察一下这道题,发现n=2时,是由三个n=1时的图形
/\
/__\ 组成,而n=3时,是由三个n=2的图形
/\
/__\
/\ /\
/__\/__\ 组成。所以刚好满足分冶的思想,将一个大的三角图腾分成上,左下,右下三个小部分,而这三个小部分又可以继续细分为更小的三个部分......最后直到最小的n=1时的图形
/\
/__\ 。而且我们可以观察到如果将这些图形存入到一个数组中,那么可以得出当输出一个正整数为n的图形时,需要一个2^n行2^(n+1)列的数组(图形总的大小,下面的h,w指的是复制过程中小三角形的行数和列数)。我的思路是从最左下部分开始,输入n=1时的图案,然后向右复制和向上复制,此时可以得到n=2时的图形,以这个n=2时的图形继续向右向上复制,就可以得到n>=2的图腾。
PS:
处理复制时,设置变量h为图形的高(所占的行数大小),设置变量w为图形的宽(所占列数的大小)。
向右复制:对于原有每一行的图形向右平移w个单位长度后的坐标点,就是向右复制过去的坐标点;
向上复制:对于原有的图形同时向右,向上移动h个单位后的坐标点,就是向上复制过去的坐标点。
AC代码
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int n=0;
cin>>n;
int x=pow(2,n), y=pow(2,n+1);
char**a=new char*[x+1];
for(int i=0;i<=x;i++)
{
a[i]=new char[y+1];
for(int j=0;j<=y;j++)
{
a[i][j]=' ';
}
}
a[x][4]=a[x-1][3]='\\';//这里要写两个反斜杠,一个反斜杠是转义字符
a[x][1]=a[x-1][2]='/';
a[x][2]=a[x][3]='_';
if(n>1)
{
int w=4,h=2;
for(int k=1;k<n;k++)
{
for(int i=0;i<h;i++)
{
for(int j=1;j<=w;j++)
{
a[x-i][j+w]=a[x-i][j];
a[x-i-h][j+h]=a[x-i][j];
}
}
w*=2;
h*=2;
}
}
for(int i=1;i<=x;i++)
{
for(int j=1;j<=y;j++)
{
cout<<a[i][j];
}
cout<<endl;
}
return 0;
}
如果有哪里思路出错或者可以优化的,请大家多多指教