打印沙漏
来源:互联网 发布:为mysql设置密码 编辑:程序博客网 时间:2024/05/17 04:24
1.题目描述
自测-1 打印沙漏 (20分)
本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:
19 *
输出样例:
2.我的解题思路
- 首先,写出根据行数计算“沙漏”需要用到的符号数目,这里我采用递归的方式实现,从题目示例中很容易看出,“沙漏”符号数目每次相对于上一次增加2*n个符号,其中n代表行数。示例代码如下:
int count(int n){ if (n == 1){ return 1; } else { if(n % 2 == 0){ n = n - 1; } return count(n - 2) + n * 2; }}
特别说明:从题目可知,行数为奇数,每行符号数目也为奇数,所以每次递减都是-2。
- 计算行号,这里用flag表示,确定flag需要用到count函数,当输入符号数N处于count(n - 1)和count(n)之间时,flag=n - 1;同样由于行数时奇数,所以从1开始递增,每次增加2,即flag=n-2;示例代码如下:
for(i = 1; i <= 33; i = i + 2){ if(N == 1){ num = count(1); flag = 1; break; } if(N >= ((i - 2) * (i - 2)) && N < i * i){ if(N > count((i - 2)) && N < count(i)){ num = count((i - 2)); flag = i - 2; } else { num = count(i); flag = i; } } } if(flag != 1 && N - num > flag * 2){ for(t = flag; t <= 45; t = t + 2){ if(N > count((t - 2)) && N < count(t)){ num = count((t - 2)); flag = t - 2; break; } } }
特别说明:num用于记录需要的符号数,因为最后需要打印有多少符号没有使用,即需要打印N-num。
我最开始写的时候没有最下面的if块,导致最大值计算错误。最开始计算思路为:打印格式为方阵,那么符号数目应该在两个相邻flag^2之间,但是二次方增加很快,其中会剩余大部分的符号数目没有使用,不符合题目要求。这也是为什么上一个for循环的终止点在33,因为33^2已经超过题目要求的1000了。
后面的if语句首先判断此时的flag是否能够再添加两层,如果可以,说明此时“沙漏”还不是最大,需要继续判断。里面的for循环用于寻找最大“沙漏”,临界点45是利用count函数计算出来的,此时“沙漏”需要的符号数目正好超过最大值1000,所以取该节点。通过count函数不断对比,找出正确的num和flag。
- 打印“沙漏”,逐行打印沙漏,首位两行符号数目与flag层数相同,逻辑简单,可以直接if选择出来打印,每打印一行沙漏都需要一个换行符。然后是上半部分沙漏,逐层递减,根据层数增加,左右各向中间缩进,例如:首行是第0行,全部打印;第1行需要从1开始打印符号,前面的打印空格,尾部打印到flag-j处为止。示例代码如下:
for(j = 0; j < flag; j++){ if(j == 0 || j == (flag - 1)){ for(k = 0; k < flag; k++){ printf("%c", c); } printf("\n"); } else { if(j <= ceil(flag / 2)){ for(k = 0; k < (flag - j) ; k++){ if(k < j){ printf(" "); } else { printf("%c", c); } } printf("\n"); } else { for(k = 0; k <= j; k++){ if(k < (flag - 1 - j)){ printf(" "); } else { printf("%c", c); } } printf("\n"); } } } printf("%d", (N - num));
特别说明:最开始提交,一直提示格式错误。后面看了网上其他人的代码发现,沙漏的右半部分并不是打印的空格,到了后面就结束了。红框标出部分不是空格,直接换行了,经过修改,有了上面的代码。
参考链接
题目链接
解题参考
解题参考2
最后寄语
写这篇博客,只是记录下自己解题的过程,可能解法缺陷很大,由于代码完成比较仓促,看起来也不是简洁,有很多重复代码。所以附上别人的解题思路给大家参考。最后,一家之言,欢迎拍砖。
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏
- 打印沙漏形
- pat_b_1027 打印沙漏
- 1027 打印沙漏
- 第一次只出现一次的字符
- 每天进步一点点
- shell 脚本中 1>、2>、2>&1 的作用
- GCD应用
- Dos常用命令
- 打印沙漏
- MyEclipse下配置mysql驱动的方法
- LeetCode 230: Kth Smallest Element in a BST 查找二叉排序树
- hive内外部表查询
- c中volatile的作用
- IEEE802.1 802.11协议标准
- error: Error parsing XML: unbound prefix
- PAT 1077. Kuchiguse (20)
- mosquitto安装完成