题目大意:
输出共n层的如下图形
/\
/__\
思路:
首先,我题目简化的有点不完整,所以我把n=1到n=4的图形放出来,方便大家理解:
n=1
/\
/__\
n=2
/\
/__\
/\ /\
/__\/__\
n=3
/\
/__\
/\ /\
/__\/__\
/\ /\
/__\ /__\ //中间有空,没错
/\ /\ /\ /\
/__\/__\/__\/__\
n=4
/\
/__\
/\ /\
/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\ /__\/__\
/\ /\ /\ /\ //这里也有空
/__\ /__\ /__\ /__\
/\ /\ /\ /\ /\ /\ /\ /\
/__\/__\/__\/__\/__\/__\/__\/__\
所以这道题并不和简化的题目描述完全一样。
—————————————————下面开始分析—————————————————
不难发现,这道题的图形是先向右复制一个,再向右上方复制一个。
也就是说:
n=1
/\
/__\
向右复制:
/\ /\
/__\/__\
向上复制:
/\
/__\
/\ /\
/__\/__\
就成了n=2的图形。
但是这样有一个缺陷:第一个图形必须放在二维数组的底端!(不然无法向上复制),而你又不好计算它要放置在第几行!
所以就想到了另外一种方法:
1.将n=1的三角形倒置:
\--/ //没法打“上划线”,请见谅。
\/
2.向右复制
\--/\--/
\/ \/
3.向右下方复制
\--/\--/
\/ \/
\--/
\/
就成了n=2的倒置图形
最后倒过来输出就可以啦!
总结步骤:
1.储存倒置的n=1图形
2.递推,每次往右和右下复制图形
3.倒置输出
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
long long h,l; //表示现在递推到的图形的行数和列数
int n;
char c[3001][3001]; //储存图形
void copy_right() //向右复制
{
for (long long i=1;i<=h;i++)
for (long long j=1;j<=l;j++)
c[i][l+j]=c[i][j]; //公式,可以自己推
}
void copy_down() //向右下方复制
{
for (long long i=1;i<=h;i++)
for (long long j=1;j<=l;j++)
c[h+i][(l/2)+j]=c[i][j]; //公式,还是可以自己推
}
int main()
{
for (int i=1;i<=3000;i++)
for (int j=1;j<=3000;j++)
c[i][j]=' '; //初始化
scanf("%d",&n);
c[1][2]=c[1][3]='_';
c[1][1]=c[2][2]='\\';
c[1][4]=c[2][3]='/'; //储存n=1的图形
h=2;
l=4; //n=1的图形右2行4列
for (int i=2;i<=n;i++)
{
copy_right();
copy_down();
h*=2;
l*=2; //重置行列
}
for (long long i=h;i>=1;i--)
{
for (long long j=1;j<=l;j++) //开始输出
{
if (c[i][j]==' ') cout<<" ";
if (c[i][j]=='\\') cout<<"/"; //注意!因为要倒过来,所以线的方向也要倒过来!
if (c[i][j]=='/') cout<<"\\"; //同上!!!
if (c[i][j]=='_') cout<<"_";
}
puts(""); //换行
}
return 0;
}