PAT甲级 1016 Phone Bills(模拟、map)

题目说明:

给你一个月内多个用户的电话拨打和挂断时间,让你计算他们这个月的电话账单,且每个小时内的资费有所不同

输入输出解释:

Sample Input:

10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
10
CYLL 01:01:06:01 on-line
CYLL 01:28:16:05 off-line
CYJJ 01:01:07:00 off-line
CYLL 01:01:08:03 off-line
CYJJ 01:01:05:59 on-line
aaa 01:01:01:03 on-line
aaa 01:02:00:01 on-line
CYLL 01:28:15:41 on-line
aaa 01:05:02:24 on-line
aaa 01:04:23:59 off-line

输入注意:

  1. 同一用户连续的on-line与off-line才算一次呼叫,如果不连续则忽略
  2. 只会在一个月内,不会跨月份
  3. 资费给的是 美分/分钟,100美分 = 1美元

Sample Output:

CYJJ 01
01:05:59 01:07:00 61 $12.10
Total amount: $12.10
CYLL 01
01:06:01 01:08:03 122 $24.40
28:15:41 28:16:05 24 $3.85
Total amount: $28.25
aaa 01
02:00:01 04:23:59 4318 $638.80
Total amount: $638.80

输出注意:按姓名字母表顺序排序(样例是好像逆序的?)

思路:

先接收输入,将每次拨出和挂断信息存入结构体中,输入时将时间点换算成总分钟方便计算时间差,然后用sort将同一客户的通话记录按时间增序排序,不同客户按姓名增序排序
之后用map将姓名和成对的通话记录对应起来,输出其时间差和相应花费
比较复杂,是目前最难的一道

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>  //sort函数需要
#include<map>
using namespace std;

struct call
{
    string name;
    int mon, day, hou, min, type, time;
    double cost = 0.00;
};
bool cmp(call a, call b)
{
    return a.name == b.name ? a.time < b.time : a.name < b.name;
}
int main()
{
    vector<double>cost;    //注意钱是浮点数
    vector<call>calls;
    map<string, vector<call>>bills;
    double day_cost = 0.00;        
    for(int i = 0; i < 24; i++)
    {
        double t;
        cin>>t;
        day_cost += t * 60;
        cost.push_back(t);
    }
    day_cost /= 100;  
    int n;
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        call c;
        cin>>c.name;
        scanf("%02d:%02d:%02d:%02d", &c.mon, &c.day, &c.hou, &c.min);  //匹配
        c.time = (c.day - 1)* 24 * 60 + c.hou * 60 + c.min;
        double t = 0.00;
        for(int j = 0; j < c.hou; j++)
            t += cost[j] * 60;
        t += c.min * cost[c.hou];
        c.cost = t / 100;
        string s;
        cin>>s;
        if(s == "on-line")
            c.type = 0;
        else
            c.type = 1;
        calls.push_back(c);
    }
    sort(calls.begin(), calls.end(), cmp);
    for(int i = 1; i < n; i++)
    {
       if(calls[i - 1].name == calls[i].name && calls[i - 1].type == 0 && calls[i].type == 1)  //同一个人相邻的拨出挂断才有效,其他忽略
         {
            bills[calls[i].name].push_back(calls[i - 1]);
            bills[calls[i].name].push_back(calls[i]);
         }
    }
    
    for(auto c : bills)
    {
        double total_cost = 0;
        cout<<c.first<<' ';
        vector<call> t = c.second;
        printf("%02d\n", t[0].mon);
        for(int i = 0; i < t.size(); i += 2)
        {
            printf("%02d:%02d:%02d ", t[i].day, t[i].hou, t[i].min);
            printf("%02d:%02d:%02d ", t[i + 1].day, t[i + 1].hou, t[i + 1].min);
            double diff_cost = day_cost * (t[i + 1].day - t[i].day) + t[i + 1].cost - t[i].cost;
            total_cost += diff_cost;
            cout<<t[i + 1].time - t[i].time<<" $";
            printf("%.2f\n",diff_cost);
        }
        cout<<"Total amount: $";
        printf("%.2f\n", total_cost);
    }
}

结果:

posted @ 2021-03-04 17:38  liushz  阅读(58)  评论(0)    收藏  举报