• pat 甲级测试题目 -- 1016 Phone Bills


    题目链接

    题目描述

    要求计算银行账单。
    输入
    第一行给你一天24小时(00:00~01:00 ...)每个小时每分钟的话费,单位是美分
    第二行给你顾客列表(N 个)
    接下来的 N 行是顾客的账单详情
    CYLL 01:01:06:01 on-line
    姓名 月:日:小时:分钟 状态
    CYLL 01:28:16:05 off-line
    姓名 月:日:小时:分钟 状态
    on-line 和 off-line 必须一一对应该记录才有效

    输出
    对于输入有效的顾客,给出该顾客这个月的账单,格式如下
    CYJJ 01
    姓名 月份
    01:05:59 01:07:00 61 $12.10
    通话开始时间 通话结束时间 话费
    Total amount: $12.10
    这个月的总额话费

    注意:
    每次的输入,顾客的月份都是一样的。
    测试用例中会出现跨天的情况。

    分析

    看到这道题目之后,我考虑过单纯的使用 map 或者结构体存储数据,最后确定用 map<string, vector>,也就是map + vector + 结构体 的方式存储。尽管成功的存储了,但是到了处理数据这里,对于姓名排序以及时间排序的处理让我着实头痛。无奈就去参考了网上的代码。参考网址
    不得不说柳神真的是名不虚传。不仅用总计日时分的时间解决了时间上的排序问题,而且用总计日时分的话费解决了跨天的话费计算问题,这两个方法都有共性吧。。。学习到了!我参考(抄袭←_←)柳神的代码后,将其思路列在代码注释里面了

    实现

    #include <iostream>
    #include <vector>
    #include <map>
    #include <algorithm>
    #include <string>
    
    using namespace std;
    
    struct node {
        string name;
        int month, day, hour, minute, statue, time; // 定义 time 用于比较时间
    };
    
    bool cmp(node a, node b) {
        return a.name == b.name ? a.time < b.time : a.name < b.name; // 按照姓名比较,姓名相同按照时间比较,方便计算费用
    }
    // 计算总时间的话费,用于解决跨天问题
    double CallSpend(node cus, int* rate){
        double total = rate[cus.hour] * cus.minute + cus.day * rate[24] * 60;
        for (int i = 0; i < cus.hour; ++i) {
            total += rate[i] * 60;
        }
        return total/100;
    }
    
    
    int main() {
        int rate[25] = {0}, n;
        // 接收计费数据
        for (int i = 0; i < 24; ++i) {
            cin >> rate[i];
            rate[24] += rate[i]; // 将一天的话费数据计算出来,用于解决跨天计算话费的问题
        }
        cin >> n;
        vector<node> custom(n);
        for (int i = 0; i < n; ++i) {
            cin >> custom[i].name;
            scanf("%d:%d:%d:%d", &custom[i].month, &custom[i].day, &custom[i].hour, &custom[i].minute);
            string stemp;
            cin >> stemp;
            custom[i].statue = ((stemp == "on-line") ? 1 : 0);
            custom[i].time = custom[i].day * 24 * 60 + custom[i].hour * 60 + custom[i].minute;
        }
        // 对顾客数据进行排序
        sort(custom.begin(), custom.end(), cmp);
        // 用 map 存储数据,将同一个顾客的月账单统一
        map<string, vector<node>> list;
        for (int i = 1; i < n; ++i) {
            if (custom[i].name == custom[i - 1].name && custom[i - 1].statue == 1 && custom[i].statue == 0) {
                list[custom[i - 1].name].push_back(custom[i - 1]);
                list[custom[i].name].push_back(custom[i]);
            }
        }
        // 遍历 map 输出账单
        for (auto li : list) {
            vector<node> temp = li.second;
            cout << li.first;
            printf(" %02d
    ", temp.front().month);
            double total = 0;
            for (int i = 1; i < temp.size(); i+=2) {
                // 计算一次通话记录的话费
                double t = CallSpend(temp[i], rate) - CallSpend(temp[i-1], rate);
                printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f
    ", temp[i-1].day, temp[i-1].hour, temp[i-1].minute, temp[i].day, temp[i].hour, temp[i].minute, temp[i].time - temp[i-1].time, t);
                total += t;
            }
            printf("Total amount: $%.2f
    ", total);
        }
        return 0;
    }
    

    希望能帮到大家

  • 相关阅读:
    _MSC_VER
    git之撤销修改
    vi/vim如何添加或删除多行注释
    C++ 读取文件数据和输出数据到文件
    git上传本地单独修改的文件
    Git学习笔记
    C++中类的声明
    linux中ldconfig的使用介绍
    #define 和 typedef 中的##
    find、xargs、grep基本用法
  • 原文地址:https://www.cnblogs.com/Breathmint/p/10346631.html
Copyright © 2020-2023  润新知