PTA——剥洋葱

    

7-1 剥洋葱(15 分)

布告,布告! 应老师要求,我们要做一道打印图形的题目,这是程序员最基本的能力。 那废话不多说,我们来说要求的图形 AAAAA ABBBA ABCBA ABBBA AAAAA 就是外到内,从A到Z。每一层都是一种字母,最里面的一层为一个,即最中心的一个。

输入格式:

一行,一个整数,即图形的层数

输出格式:

如上述图形

输入样例:

3

输出样例:

AAAAA
ABBBA
ABCBA
ABBBA
AAAAA


    这个题开始想的时候真的很头痛,不知道怎么输出。其实这可以看成一个数组,可以发现这个数组是一个正方形的,最外面一层全是A,向里面一层全是B,依次下去。如果输入的是26的话,会有26层,从外向内是A——Z。


(首先注明,这张图以及下面那张四分之一的图是我在其他博客里找到的,所以说我是有借鉴大佬的博客的)

我们可以把打出来的字符矩阵看成数组的形式,如上图显示就是打印n=4时的字符矩阵,蓝色的是A,浅蓝色的是B,黄色的是C,红色的是D。可以发现,他是有规律的,从外向内一层一层的,就像剥洋葱一样。我们还可以发现,这个数组是对称的,上下对称,左右对称,所以我们只要确定出来1/4数组的内容就可以通过“折叠”来把数组整个确定下来。

如上图,这就是1/4数组,在可以可以发现,蓝色的(即A)数组坐标中较小的是0,浅蓝色的(即B)数组较小的是1,黄色的(即C)数组坐标中较小的是2,红的色(即D)数组坐标中较小的是3。由此可见,每一个字符对应了数组中不同的特征,所以可以用这个特征来确定数组每个位置对应的字符。然后向右对称,再然后让下对称。(这是数组的左上角,数组的右下角也有对应的特征,A中较大的都是6,B中较大的都是5,C中较大的都是4,D中是3。但是左下角的右上角则不一样。)

下面代码是从1开始的,因我我感觉从一开始更好想,我习惯从1开始。


#include<stdio.h>
int min(int x,int y)          \\这个函数是比较数组坐标那一个小的函数,返回两者之中的较小的
{
    if(x<y)
        return x;
    else
        return y;
}


int main()
{
    int n,i,j;
    char **p;      \\这是定义了一个二级指针,下面用二级指针动态申请二维数组。
    char a[27]={'\0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};  \\首先定义一个字符数组,给其赋值,我这里是从1开始的。
    scanf("%d",&n);
    p=(char **)malloc((2*n-1)*sizeof(char));    \\这是申请2*n-1行。
    for(i=1;i<2*n;i++)                            \\这个for循环是对上面申请的每一个在申请2*n-1列,这样就是2*n-1行2*n-1列的数组 了。
    p[i]=(char *)malloc((2*n-1)*sizeof(char));  
    for(i=1;i<=n;i++)                 \\这里是先确认二维数组1/4(右上角对应的字符)
        for(j=1;j<=n;j++)
        {
            int x=min(i,j);           \\调用min函数,返回坐标中较小的
            p[i][j]=a[x];            \\较小的为1就对应A(即a[1]),较小的为二即对应B(a[2]),这里就体现出上面数组a的作用了,有了数组a,就不用if判断是几对应谁了,以前我用了26个if判断26个对应的字母
            
        }
    
    for(i=1;i<=n;i++)           
        for(j=1;j<=n;j++)              \\这里是将数组向右对称,行数是从1——n,列数是从1——n,一行一行进行对称。
        {
            p[i][2*n-j]=p[i][j];        \\第一行第一列对称的第一行第2*n-1列,第一行第二列对应到第二行2*n-2列,所以行不变,列对称。
        }
    
    for(i=1;i<=n;i++)             \\这里是向右对称之后的向下对称。行数从1——n,列数从1——2*n-1(因为上面已经向右对称了)
        for(j=1;j<2*n;j++)
            p[2*n-i][j]=p[i][j];         \\第一行第j列对应第2*n-1行第j列,即第i行第j列对应第2*n-i行第j列(i<=n)        列不变,行变。
    
    for(i=1;i<2*n;i++)
    {
        for(j=1;j<2*n;j++)
            printf("%c",p[i][j]);             \\输出数组,就能呈现出洋葱的效果。
        printf("\n");
    }
    return 0;
}

   

    


猜你喜欢

转载自blog.csdn.net/weixin_41423494/article/details/80619652
PTA