L1-002 列印沙漏
阿新 • • 發佈:2018-12-10
L1-002 列印沙漏
本題要求你寫個程式把給定的符號列印成沙漏的形狀。例如給定17個“*”,要求按下列格式列印
*****
***
*
***
*****
所謂“沙漏形狀”,是指每行輸出奇數個符號;各行符號中心對齊;相鄰兩行符號數差2;符號數先從大到小順序遞減到1,再從小到大順序遞增;首尾符號數相等。
給定任意N個符號,不一定能正好組成一個沙漏。要求打印出的沙漏能用掉儘可能多的符號。
輸入格式:
輸入在一行給出1個正整數N(<=1000)和一個符號,中間以空格分隔。
輸出格式:
首先打印出由給定符號組成的最大的沙漏形狀,最後在一行中輸出剩下沒用掉的符號數。
輸入樣例:
19 *
輸出樣例:
*****
***
*
***
*****
2
個人思路:
列印沙漏這道題我用了好幾種方法來做,最終總結出來還是以下的方法最容易理解。我們得明白沙漏是個對稱圖形,所以我們只要解決上半部分的圖形,下半部分的影象就可以迎刃而解了。
首先先確定上半部分圖形的列數,通過一個while語句確定列數,剩下的點自然就是剩餘點;第二,定義一個輸出空格函式和輸出字元函式,輸出空格和字元。
那麼問題來了,如何確定字元數和空格數呢?
我們先假設第一列是一個字元,那麼第二列是3個字元,第三列是五個字元(上半部分的影象)....所以第n列的字元數就是2*n-1,字元數確定;我們再來看看第二列和第一列相差1個空格(字元後面的空格不用管,直接“\n”就可以解決),第三列和第一列相差2個字元,找規律可以得出,第n列和第m列(n>m)相差(n-m)個空格數(下半部分的圖形依舊如此)。
只要解決空格數和字元數這道題就已經是OK了!
不足之處望大家指出,本人一定加以改正和改進,謝謝!
原始碼:
#include<iostream> #include<cstdio> using namespace std; void outputChar(int n, char c); /*輸出字元*/ void outputSpace(int n); /*輸出空格*/ int main(){ int n; char c; cin>>n>>c; if(n>1000||n<1){ /*n大於1000或者n小於1則無效*/ return 0; } if(n<7){ /*n小於7則輸出一個符號*/ cout<<c<<endl<<n-1; return 0; } int t = n-1; /*除去中間的一個字元,剩下的點賦值給t*/ int count = 0; /*標記上半部分有多少列*/ while(t>0){ count++; /*第count+1列有(count+1)*2-1個字元,因為影象是對稱所以還要乘以2*/ /*((count+1)*2-1)*2 = (4 * count + 2) */ t -= (4 * count + 2); } t += (4 * count + 2); /*當t小於0時則恢復到剩餘的點數*/ int count2 = count; /*標記,用count2代替count*/ /*輸出沙漏形狀上半部分*/ while(count2>0){ int x = count - count2; /*空格的個數*/ outputSpace(x); /*輸出空格*/ outputChar(count2*2-1, c); /*輸出字元*/ cout<<endl; count2--; } /*輸出沙漏形狀下半部分*/ count2 = 2; while(count2 <= count){ int x = count - count2; /*空格的個數*/ outputSpace(x); /*輸出空格*/ /*第count2列有count2*2-1個字元*/ outputChar(count2*2-1, c); /*輸出字元*/ cout<<endl; count2++; } cout<<t; /*輸出剩餘字元個數 */ return 0; } void outputChar(int n, char c){ for(int i=0; i<n;i++){ cout<<c; /*輸出字元*/ } } void outputSpace(int n){ for(int i=0; i<n; i++){ cout<<" "; /*輸出空格*/ } }