1027 打印沙漏 (20 分)
本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:
19 *
输出样例:
2
解题思路:
根据题意,沙漏形状的字符数量可以用等差数组来表示。题目中说,输入的数字不是都能恰好组成沙漏的,所以要先求出离输入数字最近且小于输入数字的等差数组中的项。
然后根据格式打印出沙漏,最后输出剩下的项即可。经试验得出,剩下的项是0的时候也要输出。
根据格式打印出沙漏,可以将沙漏分为上下两部分进行。上半部分,空格数量从0每次加一。下半部分,空格数量从最多每次减一。
代码:
def main():
temp = [x for x in input().split()]
# 存储输入的整数和字符
N = int(temp[0])
# 得到字符总数
char = temp[1]
# 得到字符
char_numbers = 1
# 从1层开始,逐渐增加沙漏的层数。找到满足题意的组成沙漏需要的字符总数
char_in_line = 3
# 即将添加的两层中每层的字符数
while True:
if char_numbers == N:
# 如果字符总数刚好能够组成一个沙漏
break
elif char_numbers > N:
# 字符总数不能正好组成一个沙漏,这时我们在能构成的最大沙漏上多加了两层,所以需要减去这两层。
char_in_line -= 2
# char_in_line -2 之后是上次我们加上去的两层中每层的字符数量
char_numbers -= char_in_line * 2
# 字符总数减去上次加上的两层的字符总数
break
else:
char_numbers += char_in_line * 2
char_in_line += 2
# 还可以在沙漏上再添加两层的时候,字符总数加上两层需要的字符数量。
# 下次再添加的行的字符数要增加2个
char_in_line -= 2
# 退出循环后,char_in_line -2 得到顶层的字符数
# print(char_in_line)
space_number = 0
temp = char_in_line
# 从顶层开始输出,这里要保留char_in_line的值,因为在输出沙漏的下半部分的时候还需要使用这个值。
while temp != 1:
print(" " * space_number + char * temp)
# 按行打印出相应数量的空格和字符
space_number += 1
# 下一层的空格数量 加一
temp -= 2
# 下一层的字符数量减少 两个
print(" " * space_number + char)
# 打印沙漏的小蛮腰
space_number -= 1
temp += 2
# 为下半部分的打印做准备
while temp != char_in_line + 2:
# 开始打印,直到最后一行也打印了。最后一行打印后temp的值变为 char_in_line + 2
print(" " * space_number + char * temp)
# 打印出对应数量的空格和字符
space_number -= 1
# 下一层空格数量减一,觉得有些迷糊的话可以观察案例
temp += 2
# 下一层要打印的字符数量加二
print(N - char_numbers)
# 最后打印出剩余的字符数量,就算剩下0个字符也要打印一个0出来。
if __name__ == '__main__':
main()
易错点:
- 剩余字符是零的时候也要输出。
总结:
- 写出正确逻辑的代码只是开始,我们应当尽量写得优雅,虽然我也没做到(逃…)。