1027 打印沙漏 (20 分)

题目链接:

https://pintia.cn/problem-sets/994805260223102976/problems/994805294251491328

思路:

首先根据题目找到规律:

(在此先将沙漏分成3部分:上层,中层(*号只有一个的层),下层),上层与下层对称,将上层的个数记为n层,则每层的*号个数为:2*n+1;则沙漏的所用*号的总数为:$1+2*\sum_1^n(2n+1)$化简之后为:$2n^2+4n+1$

根据这个公式,算出N可以拼出的最大沙漏所需*号个数sum;

再分成上,中,下三层进行输出,

上层:设置循环,i为层数,i=n,循环n次,输出的空格数为n-i,*号数为2*i+1进行输出,记得要换行。

中层:输出的空格数为n,再输出一个*号,记得换行。

下层:设置循环,i为层数,i=1,循环n次,输出的空格数为n-i,*号数为2*i+1进行输出,记得要换行。

最后再输出N-sum即可。

填坑日记:。。。。。哇这道题有毒,我以为每行的*号之后需要再输出空格,结果这样被判断错误,也就是*号之后直接换行,根本不要再加空格,我之前还想着沙漏两边要对称来着呢(我觉得字符也要对称),简直是画蛇添足。被坑了大半天,暴躁小糖在线自闭。(我不要你觉得,我要我觉得,明学大弟子在此)

最后就是输出格式要注意一下,就是在N正好可以拼出一个沙漏,而且不会有剩余时,也要输出一个0,怪我自己审题不仔细,测试点1一直显示错误2333333,改了这个就可以了。

代码:

#include
using namespace std;
void solve()
{
	int N,n,i,j,sum=0,l=0,g=0;
	char c;
	scanf("%d %c",&N,&c);
	for(n=0;;n++)
	{
		sum=2*n*n+4*n+1;
		if(sum>N)
		break;
		else continue;
	}
	n--;
	sum=2*n*n+4*n+1; //可以用来拼出沙漏的总数
	//分成上中下三层输出	
	for(i=n;i>0;i--)     //上层
	{
		for(j=0;j0;i--)    //中层
	 	printf(" ");
	 printf("%c\n",c);
	 for(i=1;i<=n;i++)   //下层 
	 {
	 	for(j=n-i;j>0;j--)
	 	{
	 		printf(" ");
		 }
		 for(j=0;j<2*i+1;j++)
		 {
		 	printf("%c",c);
		 }
		 printf("\n");
	 }	 
	 printf("%d\n",N-sum);          

 } 
 int main()
 {
 	solve();
 	return 0;
 }

好了让我们来膜拜一下女神的代码:

#include 
using namespace std;
int main() {
    int N, row = 0;
    char c;
    cin >> N >> c;
    for (int i = 0; i < N; i++) {
        if ((2 * i * (i + 2) + 1) > N) {
            row = i - 1;
            break;
        }
    }
    for (int i = row; i >= 1; i--) {
        for (int k = row - i; k >= 1; k--) cout << " ";
        for (int j = i * 2 + 1; j >= 1; j--) cout << c;
        cout << endl;
    }
    for (int i = 0; i < row; i++) cout << " ";
    cout << c << endl;
    for (int i = 1; i <= row; i++) {
        for (int k = row - i; k >= 1; k--) cout << " ";
        for (int j = i * 2 + 1; j >= 1; j--) cout << c;
        cout << endl;
    }
    cout << (N - (2 * row * (row + 2) + 1));
    return 0;
}

OMG女神的代码真的好简洁。。。。。

分析:

每个沙漏都是从最中间一行行向上下分别扩展一行,每次扩展行都要比之前一层多2个符号,最中间一行只有 1 个符号,假设扩展的层数为 i,则扩展出去的上边需要的所有符号个数为3 + 5 + 7 + … + (2i+1) = (3 + 2i + 1) * i / 2 = i * (i + 2),扩展出去的下边与上边同样多所以乘以2,加上最重要那一行1个符号,所以 总共需要2 * i * (i + 2) + 1个符号,所以i从0到N,找满足(2 * i * (i + 2) + 1) > N的最小的 i,因为符号不能超过N,所以只能扩展出去 i-1 行,用变量row表示从最中间一行需要扩展出去的行数,row = i – 1,接下来开始输出,上面的每一行,对于扩展出去的第 i 层需要输出row – i个空格,接着输出i * 2 + 1个符号c和换行符;对于最中间一行,需要输出row – 1个空格、符号c和换行符;对于下面的每一行,对于扩展出去的第i层,需要输出row-i个空格,接着输出i * 2 + 1个符号c和换行符,因为用掉的符号数为2 * row * (row + 2) + 1,所以最后输出剩下没用掉的符号数为N – (2 * row * (row + 2) + 1)~(这段分析内容来自女神的博客,并不是本人进行代码再次分析,博客地址:https://www.liuchuo.net/archives/555)

今日份吐槽:代码感觉就是别人家的好看。

你可能感兴趣的:(PAT乙级刷题)