《数据结构》开课前的一些小作业练习,可能因为一个寒假都没有打C++手生了,整个寒假都在帮拍电影做后期特效,导致这道题居然用了两个钟去AC,深感惭愧,作个标记吧,下面上题。

一首好曲推荐:同时我也设置成了我的博客背景音乐

《开启新征程》 —— 流浪地球电影的片尾曲

收藏链接:https://music.163.com/#/song?id=1343461538

------------------------------------------------题目----------------------------------------------------------

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

  1. *****
  2. ***
  3. *
  4. ***
  5. *****

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

输入格式:

输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。

输出格式:

首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。

输入样例:

  1. *

输出样例:

  1. *****
  2. ***
  3. *
  4. ***
  5. *****

------------------------------------------------题目----------------------------------------------------------

(一) 题目分析:

  首先经过题目分析,可知特殊符号数跟行数有着某种特殊关系,除去中间的一颗星星*,可以发现上半部分的是个递增的等差数列:3,5,7,9,.......,可得通项公式2n+1(其中n = 上半部分行数 = 下半部分行数)

  那么求和即为Sn = n2+2n,这是上半部分的。那么上下两部分即可得到:

  总**用量:2( n2+2n) =  2n2+4n

  到这里我们就可以算出输入的数能生成几行了。

(二)代码分块:

  首先,先计算得出能上下部分各能生成几行:

  1. for(i = ;;i++)
  2. {
  3. temp = *i*i+*i;
  4. if(temp > cNumber-) break;
  5. Max = temp;
  6. }

  temp临时存放下一行所需的总量,如果这个总量超过了输入的量数,那么就break打破永真循环,不把temp值赋值给Max行数,否则就把temp的行数赋值给Max变量。

  第二步,绘制上半部分:

  1. for(temp = i-;temp>;temp--)
  2. {
  3. for(int count = ;count != (i-)-temp;count++) printf(" ");
  4. for(int count = ;count<(*temp+);count++) printf("%c",symbol);
  5. printf("\n");
  6. }

  这时候的temp就是行数了,i-1是因为永真循环的时候被i++多了一次,所以需要减掉,以样例为例,输入19后,此时temp应该为2,也就是给上半部分绘制两行。

  因为题目要求中心对齐,我们同时也发现空格和行数之间的关系,例如第一行是没有空格的,第二行有一个空格,第三行有两个空格,所以通过空格数和行的关系去输出即可,然后每一行最后都换行,代码就形成了。

  第三步,绘制下半部分:

  1. for(temp = ;temp<=i-;temp++)
  2. {
  3. for(int count = ;count != (i-)-temp;count++) printf(" ");
  4. for(int count = ;count<(*temp+);count++) printf("%c",symbol);
  5. printf("\n");
  6. }

  此时需要注意,最外层的for,在绘制上半部分的时候,是temp>0,是不取边界的,如果取了边界会使上部分多画一行单个*。我这里选择的是下半部分取绘制这单个*,因此需要temp<=i-1,取到边界。

(三)AC代码:

  1. #include<iostream>
  2. #include<stdio.h>
  3. using namespace std;
  4. int cNumber,Max,i,temp;
  5. char symbol;
  6. int main()
  7. {
  8. scanf("%d %c",&cNumber,&symbol);
  9. for(i = ;;i++)
  10. {
  11. temp = *i*i+*i;
  12. if(temp > cNumber-) break;
  13. Max = temp;
  14. }
  15. for(temp = i-;temp>;temp--)
  16. {
  17. for(int count = ;count != (i-)-temp;count++) printf(" ");
  18. for(int count = ;count<(*temp+);count++) printf("%c",symbol);
  19. if(temp != ) printf("\n");
  20. }
  21. for(temp = ;temp<=i-;temp++)
  22. {
  23. for(int count = ;count != (i-)-temp;count++) printf(" ");
  24. for(int count = ;count<(*temp+);count++) printf("%c",symbol);
  25. printf("\n");
  26. }
  27. printf("%d",cNumber-Max-);
  28. return ;
  29. }

(四)AC截图:

(五)解后分析

  题目难度不大,刚开始可能手生,在写for的时候总是渲染多一行或者找错最大行数。

  推荐知识:

  1、将声明变量放在main主函数外,可以申明稍微大型一点的变量,因为main的函数栈容量有限。同时还有一个好处,在函数外申明数组的时候会自动默认全为0清零

  2、推荐使用scanf("%d %c",&cNumber,&symbol); printf("%c",symbol); 这种C语言输入输出方式,在ACM中将能大大减少输入输出所占用的算法时间

(六)优质解法更新:

  这是在写博客的时候突然想到可以从上到下一次性绘图,写完博客就去试了一下,还真的可以,空间复杂度大大降低了,同样也AC,现在贴上代码:

  1. #include<iostream>
  2. #include<cmath>
  3. #include<stdio.h>
  4. using namespace std;
  5. int cNumber,Max,i,temp;
  6. char symbol;
  7. int main()
  8. {
  9. scanf("%d %c",&cNumber,&symbol);
  10. for(i = ;;i++)
  11. {
  12. temp = *i*i+*i;
  13. if(temp > cNumber-) break;
  14. Max = temp;
  15. }
  16. for(temp = *(i-);temp>=;temp--)
  17. {
  18. for(int count = i-;count != abs((i-)-temp);count--) printf(" ");
  19. for(int count = ;count<*abs(temp-i+) + ;count++) printf("%c",symbol);
  20. printf("\n");
  21. }
  22. printf("%d",cNumber-Max-);
  23. return ;
  24. }

可以发现内存使用量大大减少,将两块的上下绘制合并到一块之后代码空间复杂度下降很多。

注:如果有更好的解法,真心希望您能够评论留言贴上您的代码呢~

『ACM C++』PTA浙大 | 基础题 - 打印沙漏的更多相关文章

  1. 『ACM C++』PTA浙大 | 基础题 - Have Fun with Numbers

    连着这两道都是开学前数构老师的“爱心作业”,还没上课开学就给我们布置作业了,这道题有点小坑,也经常遇到类似的问题,特地拿出来记录一下. -------------------------------- ...

  2. 『ACM C++』 PTA 天梯赛练习集L1 | 021-024

    忙疯警告,这两天可能进度很慢,下午打了一下午训练赛,训练赛的题我就不拿过来的,pta就做了一点点,明天又是满课的一天,所以进度很慢啦~ -------------------------------- ...

  3. 『ACM C++』 PTA 天梯赛练习集L1 | 007-011

    真的是忙头晕了,学业.ACM打题.班级活动.自学新东西,哇这充实的大学~ ------------------------------------------------L1-007--------- ...

  4. 『ACM C++』 PTA 天梯赛练习集L1 | 036-037

    这几天比较忙,所以随便做做水题了,得赶紧把英剧搞完啊啊啊啊啊啊 ------------------------------------------------L1-036-------------- ...

  5. 『ACM C++』 PTA 天梯赛练习集L1 | 001-006

    应师兄要求,在打三月底天梯赛之前要把PTA上面的练习集刷完,所以后面的时间就献给PTA啦~ 后面每天刷的题都会把答案代码贡献出来,如果有好的思路想法也会分享一下~ 欢迎大佬提供更好的高效率算法鸭~ - ...

  6. 『ACM C++』 PTA 天梯赛练习集L1 | 029-033

    哈哈,今天开始我也是学车人了~ 开始一千多道疯狂刷题~ ------------------------------------------------L1-029------------------ ...

  7. 『ACM C++』 PTA 天梯赛练习集L1 | 025-026

    满课一天,做25的时候还疯狂WA,进度可以说是很慢了 哭泣 ------------------------------------------------L1-025---------------- ...

  8. 『ACM C++』 PTA 天梯赛练习集L1 | 018-020

    终于一周有这么一天能够安静下来好好学习打打题,还是很美滋滋的哈哈~加油加油~ ------------------------------------------------L1-018------- ...

  9. 『ACM C++』 PTA 天梯赛练习集L1 | 052-053

    今日刷题,水题水题 ------------------------------------------------L1-052------------------------------------ ...

随机推荐

  1. 概述File i/o

    1.File对象既可表示文件,也可表示目录(文件夹). 2. 创建一个File对象 File file = new File (String pathName[文件路径名]); 3.在Windows操 ...

  2. POJO对象

    POJO(Plain Old Java Objects)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称. 使用POJO名称是为了避免和 EJB混淆起来, 而且简 ...

  3. 有关background 背景图片不能显示

    首先有两个概念 绝对路径,从根目录为起点到你所在的目录: 相对路径,从一个目录为起点到你所在的目录. 例如:              ┍ A文件夹           C -|            ...

  4. 【PIC单片机】Pic单片机基础知识

    本次学习采用PIC16F877A芯片及HJ-5G 开发板 一.IO口操作 1.1 设置I/O口方向:input or output TRISx 方向寄存器 (Transport and Receive ...

  5. 基本算法思想Java实现的详细代码

    基本算法思想Java实现的详细代码 算法是一个程序的灵魂,一个好的算法往往可以化繁为简,高效的求解问题.在程序设计中算法是独立于语言的,无论使用哪一种语言都可以使用这些算法,本文笔者将以Java语言为 ...

  6. 【java开发系列】—— 深克隆和浅克隆

    Java支持我们对一个对象进行克隆,通常用在装饰模式和原型模式中.那么什么是深克隆,什么是浅克隆呢. [浅克隆],通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的. [深克隆],克隆的时候 ...

  7. Oracle数据库克隆后temp文件因路径变化无法找到问题

    Oracle数据库克隆后temp文件因路径变化无法找到出现如下报错Errors in filexxxx.trc:ORA-01157: cannot identify/lock data file xx ...

  8. Spring3+Struts2+Hibernate4+Mybatis整合的一个maven例子

    说明: 1.用了maven去搞这个demo,懒得去导jar包... 2.这个demo用了spring去做Ioc,事务的aop:用了struts2去做“MVC”(没有用到任何UI技术,有点对不起这个MV ...

  9. 【BZOJ4766】文艺计算姬(prufer序列)

    点此看题面 大致题意: 让你求一个两边各有\(n\)和\(m\)个点的完全二分图有多少个生成树. \(prufer\)序列 这是一道比较经典的利用\(prufer\)序列结论求解答案的计数题. 大致思 ...

  10. Android——HelloWorld

    今天正式加入实验室做安卓,看上去无从下手,让我想到当年学ACM一样,但是也一直搞过来了,现在又是一个新的起点. 废话不多说~~~ Hello World 安装: JDK SDK Eclipse 参考: ...