• 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;
    } 
    
  • 相关阅读:
    MCU软件最佳实践——独立按键
    MCU软件最佳实践——矩阵键盘驱动
    MCU软件最佳实践——使用printf打印数据
    CAP定理图解证明
    类型和变量
    数字ID过长 精度丢失 (已解决:后端方案)
    Springboot 异步线程池配置(小型应用)
    Java 数字 字符串 简单操作
    Java 网络请求
    Java 时间 日 周 月 季 年
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313080.html
Copyright © 2020-2023  润新知