2015年6月7日 星期日

d511:小明的作業 (23)

d511: 小明的作業 (23)

更新時間:2016/12/21
內容
  小明這學期的數學課教到了三角形,於是老師給了他們一個作業,這個星期一到星期五每個人上學時都要帶三根樹枝到學校來,如果那三根樹枝可以構成一個三角形,那天就可以加一分。給你小明所帶樹枝的長度,請你幫他看看他可以加幾分?
輸入說明
  輸入一共有 5 行,每行有 3 個整數,代表當天小明所帶的樹枝的長度。
輸出說明
  輸出一個整數,代表小明可以加幾分。
範例輸入
  1 2 3
  2 4 6
  3 4 5
  5 3 2
  1 3 5
範例輸出
  1
提示



想一想,再看解答~


我的解題想法
  先用泡泡排序法把三個數字由大到小排列,再符合數學原理「最長邊大於兩邊之差」與「最長邊小於兩邊之和」,即可以構成三角形。

程式碼
#include <stdio.h>
int main(void){
    int score=0,a,b,c,tmp;
    for(int i=1;i<=5;i++){
        scanf("%d%d%d",&a,&b,&c);
        if(a<b){
            tmp = a;
            a = b;
            b = tmp;
        }
        if(a<c){
            tmp = a;
            a = c;
            c = tmp;
        }
        if(b<c){
            tmp = b;
            b = c;
            c = tmp;
        }
        if(b-c<a && a<b+c){
            score++;
        }
    }
    printf("%d",score);
    return 0;
}
程式碼解析
#1:引入標準輸入/輸出串流。
#2:主程式開始,回傳引數int,沒有參數。
#3:宣告5個整數(int)變數「score」、「a」、「b」、「c」、「tmp」,範圍–2,147,483,648 到 2,147,483,647。並初始化 score 為 0。
#4:迴圈 for 開始。區域變數「i」,從 1 開始到 5 結束 (int i=1;i<=5;i++)。
#5:從標準輸入讀取格式化數據。讀取3個整數(%d%d%d),依序指定值給「a」、「b」、「c」。
# 6~#20:使用泡泡排序法的概念,依序比較。
# 6~#10 比較 a、b 兩數,如果 a 比 b 小,就交換兩數。
#11~#15 比較 a、c 兩數,如果 a 比 c 小,就交換兩數。
#16~#20 比較 b、c 兩數,如果 b 比 c 小,就交換兩數。
#21~#23:邏輯判斷式 if,判斷「最長邊大於兩邊之差」與「最長邊小於兩邊之和」是否成立,如果成立「score」變數加 1。
#24:迴圈 for 結束。
#25:將格式化數據顯示到標準輸出。輸出1個整數(%d)「score」。
#26:主程式回傳整數「0」。
#27:主程式結束。





進階想法
  如果還不清楚如何不用邏輯判斷式 if、switch、?:等......,就可以交換兩數的方法,請參考比較判斷式中的第16篇 d491: 我也愛偶數 (swap 版) (16) 的進階想法。現在我們要準備交換3個數字,a、b、c 為任意數字,tmp 為暫存數字。交換完後,保持 a>=b>=c 。
  tmp = (a>=b)*a + (a<b)*b;
  b = (a>=b)*b + (a<b)*a;
  a = (tmp>=c)*tmp + (tmp<c)*c;
  c = (tmp>=c)*c + (tmp<c)*tmp;
  tmp = (b>=c)*b + (b<c)*c;
  c = (b>=c)*c + (b<c)*b;
  b=tmp;
最後要判斷 (b-c<a)成立 且 (a<b+c)成立,就可以構成三角形,分數就加 1。
  score = score + (b-c<a)*(a<b+c);

程式碼
#include <stdio.h>
int main(void){
    int score=0,a,b,c,tmp;
    for(int i=1;i<=5;i++){
        scanf("%d%d%d",&a,&b,&c);
        tmp = (a>=b)*a + (a<b)*b;
        b = (a>=b)*b + (a<b)*a;
        a = (tmp>=c)*tmp + (tmp<c)*c;
        c = (tmp>=c)*c + (tmp<c)*tmp;
        tmp = (b>=c)*b + (b<c)*c;
        c = (b>=c)*c + (b<c)*b;
        b=tmp;
        score = score + (b-c<a)*(a<b+c);
    }
    printf("%d",score);
    return 0;
}
程式碼解析
#1:引入標準輸入/輸出串流。
#2:主程式開始,回傳引數int,沒有參數。
#3:宣告5個整數(int)變數「score」、「a」、「b」、「c」、「tmp」,範圍–2,147,483,648 到 2,147,483,647。並初始化 score 為 0。
#4:迴圈 for 開始。區域變數「i」,從 1 開始到 5 結束 (int i=1;i<=5;i++)。
#5:從標準輸入讀取格式化數據。讀取3個整數(%d%d%d),依序指定值給「a」、「b」、「c」。
#6~#12:3個數字的交換,由大排到小。
#13:計算分數。如果(b-c<a)成立會是1,否則會是0;如果(a<b+c)成立會是1,否則會是0。當只有兩個判斷式成立時,才能構成三角形,所以分數會加 1。
#14:迴圈 for 結束。
#15:將格式化數據顯示到標準輸出。輸出1個整數(%d)「score」。
#16:主程式回傳整數「0」。
#17:主程式結束。