目录

安徽省青少年信息学奥林匹克竞赛初中组第1题LuoguP762

安徽省青少年信息学奥林匹克竞赛初中组第1题&&LuoguP762

先放题目:

【题目背景】

. . . . . . . . . . .分。

初春的一天,正是乍暖还寒时候,狂风乍起。小可可裹紧了单薄的外衣,往小雪家中赶去。

“今天真不是个出门的时候啊!”小可可感叹道。

“但是我还有东西要买……你就陪我去下超市吧?”

在超市里,小雪一共买了 23.70 元的东西,最后却只付了 20.1 元,小可可见状很疑惑。

“超市对学生有优惠呗,最后会打八五折。”

“那也不可能是这个价啊?我想想……应该是 20.145 元才对。”

“超市结算的时候最后会去分化整,也就是说,以角作为付钱的最小单位,多的零头就不要

了。”

【问题描述】

现在,假如小可可一共买了 n 种类型的商品,第 i 种商品的单价为 ai 元,买了 bi 件,最后打八五折,并且舍去多出的小于一角的零头,你能不能帮他算算实际要付的钱数?



输入格式
输入文件名:shopping.in

第一行一个正整数 n,表示商品的种类数。

下面 n 行,每行一个两位小数 ai 和一个整数 bi,用空格隔开,分别表示第 i 种商品的单价

和购买量。注意,输入中不会省略小数点后的零。



【数据范围与提示】

提示:如果你对浮点数不熟悉的话,请尽量利用整数完成。

 对于 30% 的测试点,保证 n = 1

 对于另外 30% 的测试点,保证答案是整角;

 对于 100% 的测试点,保证 1  n  10, 0.01  ai  99.99, 1  bi 10



输出格式
输出文件名:shopping.out

仅一行,一个一位小数,表示小可可在打折并去分后要付的实际元数。注意,即使小数点后一位是 0,也要输出。



输入/输出例子1
输入:

1

23.70 1



输出:

20.1

输入/输出例子2
输入:

3

3.00 2

17.95 1

0.10 1



输出:

20.4

样例解释

【样例 1 解释】

这就是【题目背景】中的例子。



【样例 2 解释】

小可可的原购买金额为 3.00×2+17.95×1+0.10×1 = 24.05 元,
打八五折后为 24.05×85% =20.4425 元,去掉零头后为 20.4 元。

题面非常好理解,就是求购物总价值(用 double ),然后打八五折(就是

× 0.85 \times0.85

×

0.85 ),最后去掉零头(就是使用去尾法保留一位小数)。

我们先写出初步代码:

#include <bits/stdc++.h>

using namespace std;
int n;
double sum;
int main()
{
    
    cin >> n;
    while (n--)
    {
        double price;
        int num;
        cin >> price >> num;
        sum += double(price * num);
    }
    cout << fixed << setprecision(1) << double(sum * 0.85);
    cout << "\n";
    return (0);
}

但是你会发现 https://i-blog.csdnimg.cn/direct/e8697ddfe916482ea6751bff959147c5.png#pic_center

分析错因

具体什么的原因,请君来细听。

去尾法保留小数,切勿当四舍五入!

四舍五入分开讲,把要保留的小数位数后一位挑起想。

小于4舍去,大于4则向前进位去。

去尾法不同,请勿混淆同!

横批竖切保留的后一位,不管怎样,都去扬!

君思维飞翔…

不闹了,C++的 fixed and setprecision 是四舍五入,就是把保留位数的后一位拿出,如果

< 5 <5

<

5 就不进位否则进位。然后还有精度的原因所以70pts

去尾法是把保留位数的后面所有全部去掉(不包含保留那位)。

那题目里说的舍去零头就是 去尾法

那去尾法怎么表达呢?

我们既然要去尾保留一位小数那么我们可以把它用一个 int 类型来中途存储。我们把它

× 10 \times10

×

10 ,那么就会把小数往后移一位,那么小数部分的第一位就会到个位,然后再保留 int 然后

÷ 10 \div10

÷

10 类型不久能去掉尾了吗。

举个栗子

我们需要把 3.14159 保留一位小数。

3.14159 × 10 = 31.4159 3.14159\times10=31.4159 3.14159 × 10 = 31.4159

i n t ( 31.4159 ) = 31 int(31.4159)=31 in t ( 31.4159 ) = 31

d o u b l e ( 31 ÷ 10 ) = 3.1 double(31\div10)=3.1 d o u b l e ( 31 ÷ 10 ) = 3.1

这不就对了吗

Now,Let’s see the Accepted code。

#include <bits/stdc++.h>

using namespace std;
int n;
double sum;
int main()
{
    // freopen("shopping.in", "r", stdin);
    // freopen("shopping.out", "w", stdout);

    cin >> n;
    while (n--)
    {
        double price;
        int num;
        cin >> price >> num;
        sum += double(price * num);
    }
    sum *= 0.85;
    sum *= 10;
    printf("%.1lf", double(int(sum)) / 10.0);
    cout << "\n";
    return (0);
}

G o o d   b y e ! Good~bye! G oo d b ye !

T h a n k s   f o r   w a t c h i n g ! Thanksforwatching! T hank s f or w a t c hin g !

T y s m Tysm T ys m

leecher:ygg pls

Virgo:Just mark leecher!