第二章 迴圈結構程式設計
1. 函式 double floor(double x) 向下取整,返回不超過x的最大整數;函式 double ceil(double x) 向上取整,返回不小於x的最小整數。若給定的數為整數,則返回該整數。按理說返回的是整數,函式型別應該是int ,但據codeblocks提示,函式型別為double 。標頭檔案 math.h
2. eg2-1:輸出所有形如aabb的4位完全平方數(前兩位數字相等,後兩位數字也相等)。程式碼如下:
#include<iostream> #include<cmath> using namespace std; int main() {for(int a=1;a<=9;a++) for(int b=0;b<=9;b++) { int n=a*1100+b*11; int m=floor(sqrt(n)+0.5); //減少浮點運算帶來的誤差 if(m*m==n) cout<<n<<endl; } return 0; }
其中,對於減少浮點運算帶來的誤差的方法值得學習。(浮點運算誤差來自於計算機儲存浮點數的方式),當然,此題用列舉可避開開方。
3. int32_t:4位元組的整型數,uint32_t:無符號4位元組的整型數。
4. 對於 long long 型的輸入,有時為:"%lld",有時為:"%I64d",10的-6次方寫為:1e-6
5. 要計算只包含加法、減法和乘法的整數表示式除以正整數n的餘數,可以在每一步計算之後對n取餘,結果不變。
6.<time.h> <ctime> 計時函式clock() 返回程式到目前為止執行的時間。這個時間除以常數CLOCKS_PER_SEC之後得到的值以”秒“為單位。該常數與作業系統相關。
7. 熟悉Windows和Linux的命令列操作。
8. 在Windows下,輸入完畢後先按下Enter,再按CTRL+Z,最後按下Enter結束輸入。再Linux下,輸入完畢後按CTRL+D結束輸入。
9.輸入輸出重定向及自動刪除等。
10. 設計程式時考慮程式的魯棒性(robustness)。
11. 當巢狀的兩個程式碼塊中由同名變數時,內層的變數會遮蔽外層變數,有時會引起十分隱蔽的錯誤。
#include<iostream> using namespace std; int main() { int a=10; for(int i=0;i<1;i++) { int a=1; cout<<a<<endl; } cout<<a<<endl; return 0; }
輸出為:1 \n 10 \n
12. 水仙花數:(daffofil)輸出100到199中的所有水仙花數。若3位數ABC滿足ABC=A*A+B*B+C*C,則稱其為水仙花數,eg:153=1*1+5*5+3*3,所以是水仙花數。
#include<iostream> using namespace std; int main() { for(int i=100;i<1000;i++) if ( (i % 10) * (i % 10) * (i % 10) + (i / 10 %10) * (i / 10 %10) * (i / 10 %10) +(i / 100) * (i / 100) * (i / 100) == i ) cout<<i<<endl; return 0; }
13. 韓信點兵(hanxin):相傳韓信聰明過人,從不直接清點自己的軍隊人數,只要讓士兵先後以三人一排、五人一排、七人一排地變換隊形,而他每次只掠過一眼隊伍的排尾就知道總人數了。輸入包括多組資料,每組資料包含3個非負整數a,b,c,表示每種隊形排尾的人數(a<3,b<5,c<7),輸出總人數的最小值(或報告無解)。已知總人數不小於10,不超過100。
輸入樣例:
2 1 6
2 1 3
輸出樣例:
Case 1: 41
Case 2:No answer
//解法1:列舉
#include<iostream> using namespace std; int main() { int a,b,c; while(cin>>a) { cin>>b>>c; for(int i=10;i<=100;i++) { if((i-a)%3==0 && (i-b)%5==0 && (i-c)%7==0) { cout<<i<<endl; break; } else if(i==100) cout<<"No answer"<<endl; } } return 0; }
//解法2: //原理:剩餘定理。特徵數分別為70、21、15 #include<iostream> using namespace std; int main() { int a,b,c; while(cin>>a) { cin>>b>>c; int num=(70*a+21*b+15*c)%105; if(num<=100&&num>=10) cout<<num<<endl; else cout<<"No answer"<<endl; } return 0; }
14. 倒三角形(triangle):給定一個n,輸出一個n層的倒三角形。例如n=5時輸出如下:
#include<iostream> using namespace std; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { for(int j=1;j<i;j++) //輸出空格 cout<<" "; for(int j=1;j<=2*(n-i)+1;j++) //輸出# cout<<"#"; cout<<endl; } return 0; }
15. 子序列的和(subsequence):輸入兩個正整數n<m<1e-6,輸出1/n^2+1/(n+1)^2+...+1/m^2,保留5位小數。輸入包含多組資料,結束標記為n=m=0。提示:本題有陷阱。
樣例輸入:
2 4
65536 655360
0 0
樣例輸出:
Case 1:0.42361
Case 2:0.00001
#include<iostream> #include<iomanip> //輸出精度 using namespace std; int main() { int m,n,Case=0; double sum; while(cin>>n) { sum=0; cin>>m; if(m==0&&n==0) break; for(int i=n;i<=m;i++) sum+=(double)1/i/i; cout<<"Case "<<++Case<<":"<<fixed<<setprecision(5)<<sum<<endl; //set...控制位數,有fixed為小數點後開始,沒有則由最高位開始 } return 0; } //此題的陷阱就是如果除以n^2會溢位,所以要除兩次。另外一種解決方法是型別為long long型
16.分數化小數(decimal):輸入正整數a,b,c,輸出a/b的小數形式,精確到小數點後c位。a,b<=1e6,c<=100。輸入包含多組資料,結束標記為a=b=c=0。
樣例輸入:
1 6 4
0 0 0
樣例輸出
Case 1:0.1667
//由於c的值為<100,所以不能簡單的用double進行儲存輸出。
#include<iostream>
using namespace std;
int main()
{
int a,b,c,Case=0;
int result[101]; //儲存對應小數位的值
while(cin>>a)
{
cin>>b>>c;
if(a==0&&b==0&&c==0) //結束輸入
break;
int integer=a/b;
int re=a%b;
for(int i=0;i<=c;i++) //計算小數值
{
result[i]=(re*10)/b;
re=(re*10)%b;
}
if(result[c]>=5) //>=5,則進位
{
if(c>=0) result[c-1]++;
else integer++;//c為0
for(int i=c-1;i>=0;i--)
{
if(result[i]>=10) //進位的處理
{
result[i]=result[i]%10;
if(i-1>=0) result[i-1]++;
else integer++;
}
}
}
cout<<"Case "<<++Case<<":"<<integer;
if(c!=0) cout<<".";
for(int i=0;i<c;i++)
cout<<result[i];
cout<<endl;
}
return 0;
}
//解決問題:c是否為0,每一位上是否需要進位
17. 排列(permutation):用1,2,3,……,9組成的3個三位數abc,def 和 ghi,每個數字恰好使用一次,要求abc:def:ghi=1:2:3。按照“abc def ghi”的格式輸出所有解,每行一個解。提示:不必太動腦筋。
#include<iostream> using namespace std; int main() { int a[10]; for(int i=123;i<=329;i++) //abc最小為123,最大為987/3==329 { int sum=0; for(int m=1;m<=9;m++) //初始化為0 a[m]=0; int j=2*i,k=3*i; //j=def,k=ghi a[i/100]=a[(i%100)/10]=a[i%10]=1; //使用的數對應位置為1,否則為0 a[j/100]=a[(j%100)/10]=a[j%10]=1; a[k/100]=a[(k%100)/10]=a[k%10]=1; for(int m=1;m<=9;m++) //說明都使用過了一次 sum+=a[m]; if(sum==9) cout<<i<<" "<<j<<" "<<k<<endl; } return 0; }