团体程序设计天梯赛-练习集 L1-002 打印沙漏 (20分)

    科技2022-07-13  159

    L1-002 打印沙漏 (20分)

    本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

    ***** *** * *** *****

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

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

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

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

    输入样例:

    19 *

    输出样例:

    ***** *** * *** ***** 2

    本人也是借鉴了此位大牛的易错点分析

    易错点1:无多余符号记得把0输出 易错点2:符号之后的空格不需要填充,否则会报格式错误,但是符号之前的空格还是要打印的 易错点3:每行都需要换行,最后一行输出剩余符号个数也要换行

    下面给出两种不同的解题方法: 解法1: 事先计算出沙漏的字符数 :利用递推公式 an = a(n-1) + (a0 + 2*n)*2;计算出每种沙漏的字符个数,然后根据等差数列求和公式求得沙漏底层的字符个数以及一半的高度,最后for循环输出。记得把0输出!!

    #include<iostream> #include<cstring> #include<algorithm> using namespace std; char ch; int n, m, dif; int sum, half; int ans[1005]; void init(){ ans[0] = 1; for(int i = 1; i <= 1005; i ++){ ans[i] = ans[i-1] + (ans[0] + 2*i)*2; if(ans[i] >= 1000){ m = i; break; } } } //打印沙漏 int main(){ init(); cin >> n >> ch ; if(n==1){ dif = 0; }else{ for(int i = 0; i <= m; i ++){ if(ans[i]>=n){ dif = n - ans[i-1]; break; } } } sum = n - dif; half = (sum+1)/2; int margin = 1, h = 1; //margin:沙漏底部, h沙漏一半的高 for(int i = 1; ;i ++){ if(i*(1+margin)/2 == half) break; margin += 2;h++; } int m_1, m_2, space; m_1 = m_2 = margin; //上半部分 for(int i = 1; i <= h; i ++){ //先打印空格 for(int j = 1; j < i; j ++){ cout << " "; space = i-1;//保存空格个数 } for(int j = 1; j <= m_1; j ++) cout << ch; m_1-=2; cout << endl; } space--;//去掉中间部分 //下半部分 for(int i = 1; i <= h-1; i ++){ for(int j = 1; j <= space; j ++) cout << " "; for(int j = 1; j <= 1+i*2; j ++) cout << ch; cout << endl; space--; } cout << dif << endl; return 0; }

    解法2:是早期的做法,逻辑也不是很清晰,仅供参考。

    #include<iostream> using namespace std; void exchange(int &n, int &t){ int an, Sn = 0, count = 0; for(int i = 1; Sn <= n; i ++){ count = Sn; if(i==1) Sn = 1; else Sn += 2*(an) + 4; an = 2*i - 1; } t = n - count; n = count; } int main(){ int n, t = 0, sum = 0; char ch; cin >> n >> ch; exchange(n, t); int height = 0, length = 0, i; for( i = 1; sum < (n-1)/2+1; i ++){ length = 2*i -1; sum += length; } height = i - 1; int x = length; for(int i = 1; i <= height; i ++){ for(int j = 1; j < i; j ++) cout << " "; for(int j = 1; j <= length; j ++) cout << ch; cout << endl; length -= 2; } length += 2; for(int i = 1; i <= height-1; i ++){ length += 2; for(int j = 1; j <= (x-1)/2-i; j ++) cout << " "; for(int j = 1; j <= length; j ++) cout << ch; cout << endl; } cout << t << endl; return 0; }
    Processed: 0.013, SQL: 8