1. 程式人生 > >第二章 迴圈結構程式設計

第二章 迴圈結構程式設計

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;
}