先来一个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;
}
不过感觉这种还是很难李姐,我还是推荐第一种。
下课~