文章目录
题目
本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定 17 17 个 “ ∗ ” “*” ,要求按下列格式打印:
*****
***
*
***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差
2 2 ;符号数先从大到小顺序递减到
1 1 ,再从小到大顺序递增;首尾符号数相等。
给定任意
N N
个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式
输入在一行给出 1 1 个正整数 N ( ≤ 1000 ) N(≤1000) 和一个符号,中间以空格分隔。
输出格式
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例
19 *
输出样例
*****
***
*
***
*****
2
其它要求
代码长度限制:16 KB
时间限制:400 ms
栈限制:8192 KB
内存限制:64 MB
题解
解题思路
把沙漏看成两个三角形减去一,很容易看出规律,三角形的个数依次为:
1 , 3 , 5 , 7 , … , 2 n − 1 1,3,5,7,…,2n-1
,所以一个三角形的字符个数为:
n 2 n^2
,因此总的沙漏字符个数为:
2 n 2 − 1 2n^2 - 1 ,其中
n n 为沙漏的行数,从
1 1 开始。
于是得出层数:
l a y e r = s q r t ( ( N + 1 ) / 2 ) layer = sqrt((N+1)/2)
,最后根据层和对应空格(
l a y e r − 1 − j layer - 1 - j
)及符号(
2 ∗ j + 1 2 * j + 1 )的个数关系,打印出沙漏即可。
完整代码
#include<math.h>
#include <iostream>
using namespace std;
void print(char sign, int count) { // 打印 sign 字符 count 遍
while (count-- > 0)putchar(sign);
}
int main(void) {
char sign;
int N, layer;
cout << "请输入一个数字和符号:"; // 提交时注释此行
cin >> N >> sign;
layer = (int)sqrt((N + 1) / 2); // 计算沙漏的层数
for (int i = 1 - layer; i < layer; i++) {
int j = abs(i);
print(' ', layer - 1 - j); // 打印空格个数
print(sign, 2 * j + 1); // 打印符号个数
cout << endl;
}
cout << N - (2 * layer * layer - 1); // 打印剩余的个数
return 0;
}