PTA——打印沙漏

先来一个7层的沙漏分析一下成分

 

 看前三行不难发现 :行:反着看①:3,7个*                               

                                                     ②:2,5个*

                                                     ③:1,3个*

由此得到:打印*的思路:反着看行数为i时 打印2i+1个*。

前三行*总数可以用等差数列求和:sum=(3+2i+1)*i/2=i*(i+2).

那么所有*的总数:sum=2i*(i+2)+1(中间的一个*)

循环的终止条件:sum>n(给的*总数)由此得到一个sum>n时的行数的一半i,但是题目要求sum<n,所以实际的行数的一半是row = i - 1.

打印空格的思路:int j = row;打印row-j个空格;j--;

#include<stdio.h>
int main()
{
	int n;char c;
	scanf("%d %c",&n,&c);
	int row=0;
	for(int i=0;i<n;i++)
	{
		if(2*i*(i+2)+1>n)                    //得到行数的一半row。 
		{
			row=i-1;
			break;
		}
	}
	for(int i=row;i>0;i--)                   //打印上半 
	{
		for(int k=row-i;k>0;k--)
		printf(" ");
		for(int j=i*2+1;j>0;j--)
		printf("%c",c);
		printf("\n");
    }
    for(int i=0;i<row;i++)                   //打印中间一行 
    	printf(" ");
        printf("%c\n",c);
    for(int i=1;i<=row;i++)                  //打印下半 
    {
    	for(int k=row-i;k>0;k--)
    	printf(" ");
    	for(int j=i*2+1;j>0;j--)
    	printf("%c",c);
    	printf("\n");
	}
	printf("%d",n-(2*row*(row+2)+1));        //剩余* 
	return 0;
}

再提一下我见过的另一种解法:

这个求行数就比较简单粗暴:

#include<stdio.h>
#include<math.h>
int main()
{
    int n,i;
    char s;
    scanf("%d %c",&n,&s);
    int h=sqrt((n+1)/2);                               //即求row
    for(i=0;i<h;i++)
    {
        for(int j=0;j<i;j++)
            printf(" ");
        for (int j = 0; j < 2 * (h - i) - 1; j++)
            printf("%c", s);
        printf("\n");
    }                                                  //不用单独打印中间一行
     for (int i = 2; i <= h; i++)
    {
        for (int j = 0; j < h - i; j++)
            printf(" ");
        for (int j = 0; j < 2 * i - 1; j++)
            printf("%c", s);
        printf("\n");
    }
    printf("%d", n - 2 * h * h + 1);
    return 0;
}

不过感觉这种还是很难李姐,我还是推荐第一种。

下课~

猜你喜欢

转载自blog.csdn.net/qq_62795094/article/details/121816576