本題要求你寫個程序把給定的符號打印成沙漏的形狀。例如給定17個“*”,要求按下列格式打印
*****
***
*
***
*****
所謂“沙漏形狀”,是指每行輸出奇數個符號;各行符號中心對齊;相鄰兩行符號數差2;符號數先從大到小順序遞減到1,再從小到大順序遞增;首尾符號數相等。
給定任意N個符號,不一定能正好組成一個沙漏。要求打印出的沙漏能用掉儘可能多的符號。
輸入格式:
輸入在一行給出1個正整數N(≤1000)和一個符號,中間以空格分隔。
輸出格式:
首先打印出由給定符號組成的最大的沙漏形狀,最後在一行中輸出剩下沒用掉的符號數。
輸入樣例:
19 *
輸出樣例:
*****
***
*
***
*****
2
題目思路:
哎,一言難盡,本以爲是一道水題,卻在寫的時候發現寫了好久,靜不下心來。就抄了一下別人的。後來機緣巧合下,有自己重新坐下,冷靜思考。經過許多次調試,有了一些結果。簡單來說:就是大而化小。
代碼:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
char ch;
getchar();//中間的空格
ch=getchar();
int i,item=1,sum=1;//sum爲所用的符號個數,item表示最大的一行的符號個數。
for(i=0;sum<=n;i++)//這樣寫,最後sum一定大於n,會超出。
{item+=2;
sum+=item*2;
}
sum-=item*2;//得到未超出時的所需符號個數sum,(返回上一次的sum)
int ans = n-sum;//得到了最後的剩餘的符號個數;(最後輸出即可)
//接下來輸出沙漏(首先不考慮輸出下半個沙漏,先輸出一半)
int t=item-2;
int cnt=0; //第一次是0第二行應該時1,依次類推。
for(i=t;i>0;i-=2)
{
for(int k=0;k<cnt;k++)cout<<" ";//輸出空格
//cnt++如果放在這裏(判斷中)會出現無限死循環!
//(第二行判斷的時候會陷入死循環)
//放在最後就好了。
for(int j=0;j<i;j++){//輸出符號
cout<<ch;
}cout<<endl;
cnt++;
}
//下半個沙漏
cnt--;//是由於最後cnt又多加了1;
for(i=3;i<=t;i+=2)//照着上面的反過來即可(但是第一項是1)
{
cnt--;
for(int k=0;k<cnt;k++)cout<<" ";//輸出空格
for(int j=0;j<i;j++){//輸出符號
cout<<ch;
}cout<<endl;
}
cout<<ans;//還有一個剩餘個數需要輸出。。。
return 0;
}