2015年6月30日 星期二

d140:On Sale (30)

d140: On Sale (30)

更新時間:2016/12/21
0.01 to 100.0010% off
100.01 to 500.0020% off
$500.01 and over40% off
內容
  美國有一家章魚百貨公司舉辦清倉大拍賣。它的拍賣折扣如左表。但貨品的初始價格如果不滿 100 元,必須另外加收 8 元的貨物稅。
輸入說明
  測試資料每一行代表貨品的原始價格。貨品價格介1.00~10000000.00 元之間。
輸出說明
  各筆貨品依上表折扣計算,並以無條件捨去法計算到小數第二位,依下列輸出範例格式輸出。
範例輸入
  127.02
  699.99
  4.50
  1.10
  1.11
  1.12
  1.13
  120.00
  999.99
  34.00
  106.28
  119.60
  978.20
  902.00
範例輸出
  $101.61
  $419.99
  $12.05
  $8.99
  $8.99
  $9.00
  $9.01
  $96.00
  $599.99
  $38.60
  $85.02
  $95.68
  $586.92
  $541.20
提示
  若浮點數不準確,可改用整數。



想一想,再看解答~


我的解題想法:   這一題真的找了很多資源才通過測資,一直深陷萬惡深淵「0.01」!!!從通過測資的大大們那邊得知,使用scanf("%d.%d",&a,&b),也就是說整數與小數分開處理。剛好題目輸入的最大值只有1千萬,讓我做整數運算時,並不會超出整數範圍21億4千7百多萬。那麼我們來看一下如何操作吧!底下說明使用$0.01到$100.00之間的折扣,打9折。a 代表整數部分,b 代表小數部分。
    打折後,產生整數的部分:a*9/10。
    打折後,產生小數點第一位:((a*9)%10)*10。
    打折後,無條件捨去小數部分:(b*9/10)。
    小數部分相加後,產生的小數:(((a*9)%10)*10 + (b*9/10)) % 100。
    小數部分相加後,產生的整數:(((a*9)%10)*10 + (b*9/10)) / 100。
  ※故完整整數部分為 (a*9/10) + (((a*9)%10)*10 + (b*9/10)) / 100 。
  ※故完整小數部分為 (((a*9)%10)*10 + (b*9/10)) % 100 。

  把數字9替換成其他折扣。20% Off 替換成 8 ;40% Off 替換成 6 。



程式碼
#include <stdio.h>
int main(void){
    int a,b;
    while(scanf("%d.%d",&a,&b)!=EOF){
        if((a<100)||(a==100&&b==0)){
            printf("%s%d.%02d\n","$",8+(a*9/10)+(((a*9)%10)*10+(b*9)/10)/100,(((a*9)%10)*10+(b*9)/10)%100);
        }else if((a<500)||(a==500&&b==0)){
            printf("%s%d.%02d\n","$",(a*8/10)+(((a*8)%10)*10+(b*8)/10)/100,(((a*8)%10)*10+(b*8)/10)%100);
        }else{
            printf("%s%d.%02d\n","$",(a*6/10)+(((a*6)%10)*10+(b*6)/10)/100,(((a*6)%10)*10+(b*6)/10)%100);
        }
    }
    return 0;
}
程式碼解析
#1:引入標準輸入/輸出串流。
#2:主程式開始,回傳引數int,沒有參數。
#3:宣告2個整數(int)變數「a」、「b」,範圍–2,147,483,648 到 2,147,483,647。
#4:迴圈 while 開始。使用 while 搭配 scanf 檢查資料是否結束。
從標準輸入讀取格式化數據。讀取2個整數,分隔使用「.」(%d.%d),依序指定值給「a」、「b」。
#5:邏輯判斷式 if 開始。判斷 (整數部分小於100) 或 (整數部分等於100且小數部分等於0) 是否成立,如果成立,打 9 折另加 8 元貨物稅。
#6:將格式化數據顯示到標準輸出。輸出1個字串、1個整數、1個「.」與1個不足兩位填 0 的整數(%s%d.%02d)「8+(a*9/10)+(((a*9)%10)*10+(b*9)/10)/100」、「(((a*9)%10)*10+(b*9)/10)%100」。
#7:第二個邏輯判斷式 else if。判斷 (整數部分小於500) 或 (整數部分等於500且小數部分等於0) 是否成立,如果成立,打 8 折。
#8:將格式化數據顯示到標準輸出。輸出1個字串、1個整數、1個「.」與1個不足兩位填 0 的整數(%s%d.%02d)「(a*8/10)+(((a*8)%10)*10+(b*8)/10)/100」、「(((a*8)%10)*10+(b*8)/10)%100」。
#9:邏輯判斷 else。剩下的部分打 6 折。
#10:將格式化數據顯示到標準輸出。輸出1個字串、1個整數、1個「.」與1個不足兩位填 0 的整數(%s%d.%02d)「(a*6/10)+(((a*6)%10)*10+(b*6)/10)/100」、「(((a*6)%10)*10+(b*6)/10)%100」。
#11:邏輯判斷式 if 結束。
#12:迴圈 while 結束。
#13:主程式回傳整數「0」。
#14:主程式結束。