PTA 团体程序设计天梯赛 15分题 102

L1-102 兰州牛肉面(15)

题目要求

兰州牛肉面是历史悠久的美食,根据牛肉面的宽窄、配料的种类,可以细分为上百个不同的品种。你进到兰州的任何一家牛肉面馆,只说:“来一碗牛肉面!”就好像进到加州的咖啡馆说“来一杯咖啡”一样,会被店主人当成外星人……
本题的任务是,请你写程序帮助一家牛肉面馆的老板统计一下,他们一天卖出各种品种的牛肉面有多少碗,营业额一共有多少。

输入格式

输入第一行给出一个正整数 N(≤100),为牛肉面的种类数量。这里为了简单起见,我们把不同种类的牛肉面从 1 到 N 编号,以后就用编号代替牛肉面品种的名称。第二行给出 N 个价格,第 i 个价格对应第 i 种牛肉面一碗的单价。这里的价格是 [0.01, 200.00] 区间内的实数,以元为单位,精确到分。
随后是一天内客人买面的记录,每条记录占一行,格式为:

品种编号 碗数

其中碗数保证是正整数。当对应的 品种编号0 时,表示输入结束。这个记录不算在内。

输出格式 

首先输出 N 行,第 i 行输出第 i 种牛肉面卖出了多少碗。最后一行输出当天的总营业额,仍然是以元为单位,精确到分。题目保证总营业额不超过 106。

分析 

- 本题中明显有两组成对出现的数据:品种编号和单价,品种编号和数量,且品种编号为共有数据,因此本题考虑使用std::map 容器来存储这两对数据。其中注意单价价格区间[0.01,200.00],可以定义为float类型

-  输入部分:按照题目要求将数据存储到mp1(键为品种编号,值为单价)和mp2(键为品种编号,值为销售数量),在存储mp2中数据时, 需要注意如果不同顾客点了相同品种牛肉面,数量要累加,其次当品种编号为0时,输入结束,该记录不计入统计。

- 输出部分:包含两个部分(每种牛肉面的销售数量总营业额)。

每种牛肉面的销售数量:其中每行输出每个类别数量我其中直接用基于范围的for循环遍历map容器输出,但是运行发现存在顾客没有点某个类别,那么该类别和数量没有存入mp2中,导致遍历输出的时候漏掉该类别情况,因此最终使用方法如下:

  • 使用 for 循环从1遍历到 N,检查 mp2 中是否存在该品种编号。

  • 如果存在,输出对应的销售数量;如果不存在,输出0。

总营业额:

  • mp2中存入的都是点单数量大于0的类别,因此直接mp2中每种牛肉面的数量乘以对应的单价,再累加到 total_cost 中,即可得到总价。

  • 输出时题目要求精确到分,即保留两位小数,使用 std::fixedstd::setprecision(2) 控制输出格式,确保总营业额精确到分。

- 注意:最开始为了节省资源,总价total_cost我定义为了 float类型,但是运行结果显示有一处答案错误,反复测试边界条件后没有发现逻辑问题,查询发现其他正确解决方案中普遍采用了 double 类型来存储总价。将 total_cost 的数据类型从 float 改为 double 后,运行结果全部正确

代码

#include <iostream>
#include <map>
#include <iomanip>
using namespace std;
int main(){
    int N; //牛肉面种类数
    map<int,float> mp1; //存储类别(键)和单价
    map<int,int> mp2; //存储每个顾客点的类别(键)和数量
    cin >> N; 
    float price; //单价
    int type, bowls; //种类和碗数
    double total_cost = 0.00; //总价
    for(int i = 1;i <= N;i++){
        cin >> price;
        mp1[i] = price; //存储对应类别的单价
    }
    while(true){
        cin >> type >> bowls;
        //如果品种编号为0,输入结束,记录不放入mp2
        if(type == 0){
            break;
        }
        mp2[type] += bowls; //避免出现顾客点了相同类别的情况
    }
    // //每行输出每个类别的数量:存在顾客没有点某个类别,那么该类别和数量没有存入mp2中,导致遍历输出的时候漏掉该类别
    // for(const auto& pair2 : mp2){
    //     cout << pair2.second << endl; 
    // }
    //每行输出每个类别的数量
    for(int n = 1; n <= N; n++){
        // //直接三元运算符实现
        // cout << (mp2.count(i) ? mp2[i] : 0) << endl;
        //检查n键是否在mp中
        if(mp2.count(n)){
            cout << mp2[n] << endl;
        }else{
            cout << 0 << endl;
        }
    }
    //计算总价
    for(int i = 1; i <= N; i++) {
        if(mp2.count(i)) {
            total_cost += mp1[i] * mp2[i];
        }
    }
    //保留两位小数输出
    cout << fixed << setprecision(2) << total_cost; 
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值