Contents
  1. 1. 输入格式:
  2. 2. 输出格式:
  3. 3. 输入样例:
  4. 4. 输出样例:(”*”号在渲染的时候会转义,所以用代码格式了,实际输出没有前面的行号)

1027 打印沙漏 (20 分)

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“”,要求按下列格式打印(”“号在渲染的时候会转义,所以用代码格式了,实际输出没有前面的行号)

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

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

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

输入格式:

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

输出格式:

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

输入样例:

19 *

输出样例:(”*”号在渲染的时候会转义,所以用代码格式了,实际输出没有前面的行号)

1
2
3
4
5
6
*****
***
*
***
*****
2

分析:每一次打印图形的行数都是奇数行n,这里规定倒三角行数row = (n+1)/2。这样规定的好处是把问题拆分成正三角和倒三角的时候可以直接用row进行思考。首先我们考虑需要用到多少个符号,仅考虑倒三角的话:(1+2×row-1)×row/2。其余部分需要用到的符号数为倒三角符号数-1,故总符号数为2×row×row - 1。遍历查找,当有row满足2×i×i-1 > n时,row=i-1(带入边界条件看是否符合,这里是符合的)。在输出倒三角的时候,从i=row开始遍历,行号从上往下为为i ,i-1,i-2…..2,1方便打印符号个数,每一行的空格个数为row-i,其每一行的符号个数为2×i-1。输出正三角(没有尖)的时候也是如此思考,行号和打印的符号数字对应起来。此时最后一行是row,余下需要打印row-1行,从i=2开始打印,每一行的空格数是row-i,每一行的符号数是2*i-1。这里符号数和空格数除了逻辑分析,我还用了具体的实例去凑,心里有底一些。最后需要注意的是row和rest在循环之前需要赋初值,不赋初值的话n=1或n=2的时候会疯狂报错。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
using namespace std;
int main()
{
int i,j,n,rest,row=1;
char c;
cin >> n >> c;
rest = n - 1;
for (i=1;i<n;i++){
if (2*i*i-1 > n){
row = i-1;
rest = n - 2*row*row + 1;
break;
}
}
for (i=row;i>=1;i--){
for (j=row-i;j>0;j--) printf(" ");
for (j=0;j<2*i-1;j++) printf("%c",c);
printf("\n");
}
for (i=2;i<=row;i++){
for (j=row-i;j>0;j--) printf(" ");
for (j=0;j<2*i-1;j++) printf("%c",c);
printf("\n");
}
cout << rest;
return 0;
}
Contents
  1. 1. 输入格式:
  2. 2. 输出格式:
  3. 3. 输入样例:
  4. 4. 输出样例:(”*”号在渲染的时候会转义,所以用代码格式了,实际输出没有前面的行号)