#1249: 測資第1005...


B88000005 (喔~~!!XD)

學校 : 國立內壢高級中學
編號 : 4538
來源 : [118.167.234.168]
最後登入時間 :
2021-05-12 14:50:32
b227. F. 優惠方案Ⅱ -- 2008 NPSC 國中組決賽 | From: [220.138.33.50] | 發表日期 : 2009-01-24 19:32

我自己下載NPSC的測試資料...

 

跟他的輸出檔完全一樣阿= =""

 

以下是我的程式:

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main()
{
    stringstream ss("");
    int N=0;
    cin>>N;
    while(N>0){
        N--;
        int n=0,p=0,J=0,I=0;
        double i=0,j=0;
        cin>>n>>p;
        if(n%2==1){
            i=(n-1)*p*0.8+p;
        }
        else{
            i=n*p*0.8;
        }
        j=n*p*0.812;
        J=j;
        I=i;
        if(j-J!=0){
            J++;
        }
        if(i-I!=0){
            I++;
        }
        if(I<J){
            ss<<": )\n";
        }
        else if(I==J){
            ss<<"SAME\n";
        }
        else{
            ss<<"8-12=-4\n";
        }
    }
    cout << ss.str();
    return 0;
}

 

 
#1254: Re:測資第1005...


snail (蝸牛)

學校 : 新北市立板橋高級中學
編號 : 2021
來源 : [203.64.161.123]
最後登入時間 :
2024-09-27 09:40:52
b227. F. 優惠方案Ⅱ -- 2008 NPSC 國中組決賽 | From: [218.211.230.114] | 發表日期 : 2009-01-25 07:56

這很可能是傳說中的「浮點數誤差」!0.812 轉成二進位後會是一個循環小數,但是電腦中的浮點數的有效位數是有限的,後面的部份就被去掉了,因此它會是一個接近 0.812 的值而不是真的 0.812。

理論上 0.812 乘上一個 250 的倍數會變成整數,但是由於它只是一個接近 0.812 的值而不是真的 0.812,所以乘出來的數不會是整數。

更糟的每個編譯器取近似值的方法不太一樣,所以很有可能你的編譯器取出來的近似值和 ZeroJudge 上的編譯器所取出來的近似值就不同,導致不同的執行結果。

這題是很好的「浮點數誤差」的教材。

解決辦法:
1. 給它一些誤差容許值。比如說先減掉 1e-12 再無條件進位。
2. 用整數來解。如果你的總價是 total (整數),那麼折扣後的金額就是 (total * 812 - 1) / 1000 + 1。 
#1255: Re:測資第1005...


morris1028 (碼畜)

學校 : 國立花蓮高級中學
編號 : 3529
來源 : [114.37.59.62]
最後登入時間 :
2021-07-12 19:00:43
b227. F. 優惠方案Ⅱ -- 2008 NPSC 國中組決賽 | From: [118.161.215.212] | 發表日期 : 2009-01-25 13:50

  1.       scanf("%d %d",&x,&y);   
  2.       smile=(x/2*y)*6/10+(x/2*y%5!=0)+(x-x/2)*y;   
  3.        lion=x*y*812/1000+((x*y)%250!=0);   
  4.        if(lion>smile) printf(": )\n");   
  5.        else if(smile>lion) printf("8-12=-4\n");   
  6.        else printf("SAME\n"); 

這種方式就沒有誤差的可能了
採用之原因:

6/10→3/5 最簡分數 看分母

812/1000→203/250 一樣 只有整除不會+1

 
#1273: Re:測資第1005...


B88000005 (喔~~!!XD)

學校 : 國立內壢高級中學
編號 : 4538
來源 : [118.167.234.168]
最後登入時間 :
2021-05-12 14:50:32
b227. F. 優惠方案Ⅱ -- 2008 NPSC 國中組決賽 | From: [220.138.46.240] | 發表日期 : 2009-01-31 18:20

  1.       scanf("%d %d",&x,&y);   
  2.       smile=(x/2*y)*6/10+(x/2*y%5!=0)+(x-x/2)*y;   
  3.        lion=x*y*812/1000+((x*y)%250!=0);   
  4.        if(lion>smile) printf(": )\n");   
  5.        else if(smile>lion) printf("8-12=-4\n");   
  6.        else printf("SAME\n"); 

這種方式就沒有誤差的可能了
採用之原因:

6/10→3/5 最簡分數 看分母

812/1000→203/250 一樣 只有整除不會+1

 


兩位說的我都看不懂=.="",

 

我用*812/1000在第一個測資就爆了=.=""...

 
ZeroJudge Forum