2015年6月30日 星期二

c004:Beat the Spread! (28)

c004: Beat the Spread! (28)

更新時間:2016/12/21
內容
  超級盃又來了,為了打發中場休息時間,大家就來下注最後的結果會如何。大家下注的目標為兩隊最後的分數和,或者兩隊最後分數差的絕對值。給你這2個值,你能推出這2隊最後的得分是多少嗎?
輸入說明
  輸入的第一列有一個整數,代表以下有多少組測試資料。 每組測試資料一列,有2個大於等於 0 的整數 s, d,s 代表比賽結束時2隊分數的總和, d 代表比賽結束時2隊分數差的絕對值。
輸出說明
  對每組測試資料輸出一列,包含2個整數代表比賽結束時這2隊的分數,分數大的在前。如果沒有這樣的分數,請輸出「 impossible」。 請記得:美式足球的分數一定是大於等於 0 的整數。
範例輸入
  4
  40 20
  20 40
  5 1
  100 1
範例輸出
  30 10
  impossible
  3 2
  impossible
提示
背景知識
  迴圈



想一想,再看解答~


我的解題想法
假設兩隊的分數為a、b,則
  s = a+b
  d = |a-b|
我們計算 s+d ,會有兩種情況發生:
  情況一(a-b>=0):s+d=(a+b)+(a-b)=2a。
  情況二(a-b<0):s+d=(a+b)+(-(a-b))=2b。
無論哪種情況發生,我們都可以拿到某一個隊伍的比賽分數。
注意計算出來的分數不能有小數與負數。

程式碼
#include <stdio.h>
int main(void){
    int t,s,d;
    scanf("%d",&t);
    for(int i=0;i<t;i++){
        scanf("%d%d",&s,&d);
        if((s+d)%2!=0){
            printf("impossible\n");
        }else if(((s+d)/2)>s){
            printf("impossible\n");
        }else{
            printf("%d %d\n",(s+d)/2,(s-d)/2);
        }
    }
    return 0;
}
程式碼解析
#1:引入標準輸入/輸出串流。
#2:主程式開始,回傳引數int,沒有參數。
#3:宣告3個整數(int)變數「t」、「s」、「d」,範圍–2,147,483,648 到 2,147,483,647。
#4:從標準輸入讀取格式化數據。讀取1個整數(%d),指定值給「t」。
#5:迴圈 for 開始。區域變數「i」,從 0 開始到小於 t 結束 (int i=0;i<t;i++)。
#6:從標準輸入讀取格式化數據。讀取2個整數(%d%d),指定值給「s」、「d」。
#7:邏輯判斷式 if 開始。判斷 (s+d) 除以 2 的餘數是否不等於 0 ,如不等於 0 表示會產生小數。
#8:將格式化數據顯示到標準輸出。輸出字串「impossible\n」。「\n」代表換行。
#9:第二個邏輯判斷式 else if。判斷 (s+d) 除以 2 的商是否大於 s ,如大於 s 表示會產生負數。
#10:將格式化數據顯示到標準輸出。輸出字串「impossible\n」。「\n」代表換行。
#11:邏輯判斷 else。
#12:將格式化數據顯示到標準輸出。輸出2個整數,中間空格(%d %d)「(s+d)/2」、「(s-d)/2」。
#13:邏輯判斷式 if 結束。
#14:迴圈 for 結束。
#15:主程式回傳整數「0」。
#16:主程式結束。