#include <iostream>
using namespace std;

int main()
{
    int n=0;
    while(cin>>n)
    {
        for(int i=0;i<3*n;i++)
        {
            for(int j=0;j<3*n-1-i;j++)
            {
                cout<<" ";
            }
            for(int j=0;j<=i;j+=3)
            {
                if(i%3==0)
                {
                    cout<<"*     ";
                }
                if(i%3==1)
                {
                    cout<<"* *   ";
                }
                if(i%3==2)
                {
                    cout<<"* * * ";
                }
            }
            cout<<endl;
        }

        for(int i=0;i<n;i++)
        {
            for(int j=0;j<3*n-1;j++)
            {
                cout<<" ";
            }
            cout<<"*"<<endl;
        }
    }
    return 0;
}

  • 首先我们可以将打印分为两部分:上面的**树叶部分**和下面的**树干部分**。 可以发现:打印树叶部分的行数等于输入 n 的 3 倍;打印树干的行数为输入的 n 行
  • 对于树叶部分: 细看会发现:树叶部分其实是由一组一组的三行金字塔型 * 组成的(刚开始我写的时候看了好久才看出来)先打印左边的空格,每行打印 3*n-1-i 个空格,终止条件就是 j<3*n-1-i;接着打印树叶部分,由于树叶是由一组一组的三层金字塔堆叠而成,所以我们以3行叠加,控制每行打印的金字塔组数 可以发现: 每个小金字塔有一个共同点:第 1 层只打印 1 个 *;第 2 层 2 个 *;第 3 层 3 个 *而层数的控制我们可以巧妙的运用取余操作来实现:第一行余数为0;第二行为1;第三行为2这里有一点需要特别注意,那就是如果我们细看相邻之间的两座小金字塔,我们就会发现,它们间隔都是六个单位,可以从相邻两个金字塔每行间隔去数来发现这一点。所以我们就需要控制每行输出的宽度,这就是为什么三个输出 * 的域宽我设为了6打印完树叶的每一行记得换行最后就是打印树干部分了: 总共要打印 n行,每一行前 3n-1 个位置都是空格,然后一个 * ,后面剩下的又都是空格这里有一个巧妙之处就是我们直接内侧 for 循环,控制输出空格就行了,for 循环执行完后直接到下一步,那就在下一步换行的时候,连同把 * 打印出来,就达到了每行一样格式打印的效果