L1-002 打印沙漏

原题链接:打印沙漏

思路

我们可以知道打印的沙漏是对称的,假如输入19个*,实际只会用17个,有两个被舍弃了。

那么我们可以发现一半行数的数量加一起就是19/2个,又可以发现一个规律:

  • 1 = 1
  • 1+3 = \(2^2\)
  • 1+3+5 = \(3^2\)

所谓行数的一半恰好就是\(\sqrt n\)也就是\(\sqrt {(19/2)}\)

但这时又有一个问题,如果我输入1怎么半?1/2=0了,什么也不会输出

我们可以发现18/2和19/2结果一样,19/2和20/2在\(\sqrt n\)的情况下结果也是一样的,所以我们可以sqrt((n+1)/2)

代码实现

#include<iostream>
#include<algorithm>
#include<cmath>

using namespace std;

const int N = 1010;

int a[N];
int n;
char s;

int main()
{
    cin >> n >> s;
    
    a[0] = 1;
    for(int i = 1; i < 500; i++)
    	a[i] = a[i-1] + 2;
    
    int line = sqrt((n+1)/2);
    
    int surplus = n-(line*line+line*line-1);
    line -= 1;
    
    for(int i = line; i >= 1; i--)
    {
    	// 补空格
		for(int j = (a[line] - a[i])/2; j > 0; j--)  cout << " ";
		for(int k = 0; k < a[i]; k++) cout << s;
		cout << endl;
	}
	
	for(int i = 0; i <= line; i++)
    {
    	// 补空格

		for(int j = (a[line] - a[i])/2; j > 0; j--)  cout << " ";
		for(int k = 0; k < a[i]; k++) cout << s;

		cout << endl;
	}
    

    cout << surplus;
    return 0;
}

posted @ 2020-11-16 23:12  晓尘  阅读(132)  评论(0)    收藏  举报