SSLZYC 洛谷 P1498 南蛮图腾

题目大意:
输出共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;
} 
原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313080.html