题目

解题思路

本题的解题思路依旧是先确定存储结构,可以看到我们需要一个数组来存规定的每小时的花费,然后需要存储每一个人所拨打的电话记录,一个人有多条记录,那我们就用一个结构体来存名字,月,日,小时,分以及当前记录的接听状态。有了这个结构体,那我们把这些记录存在一个vector数组里面,这样题目的给的电话记录就存好了。

但是你会发现这些电话记录是乱的,而我们需要整理出每个人的通话时间及费用,那么我们还需要对这些乱的记录做一个排序,先按名字顺序排序,如果名字相同,就按sum_time的大小来排序。

排序后为了方便对结果进行输出,我们选择用一个map对其进行进一步处理,那为啥vector数组已经能排好序了,不能直接对它进行遍历呢?因为会有无法匹配的记录,如果说题目给了同一个人的3条通话记录,那么一定会有一条通话记录是多余的,这种多余的记录单纯用vector去遍历不太好处理。所以我们用map的特性,将名字相同的放在一起,这样对单个用户的通话记录的遍历就容易很多。

接下来说明本题代码的核心点:

  • 本题对时间的处理,都是以分钟为单位(老套路了,对时间的处理,要么换成秒,要么换成分钟,),比如01:01:22,表示当月1号1点22分,那就换成(1 24 60+1 * 60 + 22),是以每个月1号0点0分为基准,这样处理很方便。我们用sum_time来存这个数值,也方便后面对记录排序,同时也处理了通话记录跨天的问题。比如当月1号23点55分——当月2号0点3分,我们的处理方式可以很好的解决这一问题。
  • 电话费的问题我们依旧是相同的思路,即对每一条通话记录的时间计算其费用,例如 CYLL 01:01:06:01 on-line 这条记录,我们依然以当月0点0分为基准,对其进行费率计算。先算分钟的费率+天数的费率,再算小时的费率,本例就是6点到7点的费率 分钟 + 一天费率的总和 60 * 几号 +每个小时对应的费率的和。然后讲两个匹配的记录的费用和做差即可算出当前通话的费用。最后单位问题,题目给的是美分,要求输出美元,所以最后需要转换。

本题没有什么太大的坑,唯一的坑就是跨天的记录的处理,我们已经解决了。

实现代码

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<sstream>
#include<algorithm>
using namespace std;

typedef struct node
{
    string str;
    //status存储通话记录状态,0表示off-line,1表示on-line
    int month,day,hour,minute,sum_time,status;
}NODE;

bool cmp(NODE a,NODE b)
{
    //升序排列
    return a.str != b.str ? a.str < b.str : a.sum_time < b.sum_time;
}

//计算每个通话记录的费率
double bill(NODE a, int *price)
{
    double total = price[a.hour] * a.minute + price[24] * 60 * a.day;

    for(int i=0;i<a.hour;i++)
    {
        total+=price[i]*60;
    }

    return total/100;
}

int price[25];

int main()
{
#ifdef ONLINE_JUDGE                
#else    
    freopen("1.txt", "r", stdin);
#endif 

    int temp=0;
    for(int i=0;i<24;i++)
    {
        cin>>price[i];
        temp+=price[i];
    }
    price[24]=temp;

    int num;
    cin>>num;

    vector<NODE> v(num);

    for(int i=0;i<num;i++)
    {
        string temp;
        cin>>v[i].str;
        scanf("%d:%d:%d:%d",&v[i].month,&v[i].day,&v[i].hour,&v[i].minute);

        v[i].sum_time = v[i].day*24*60 + v[i].hour*60 + v[i].minute;

        cin>>temp;
        temp == "on-line" ? v[i].status=1 : v[i].status=0;
    }

    sort(v.begin(),v.end(),cmp);

    map<string,vector<NODE>> mmap;

    for(int i=1;i<num;i++)
    {
        if(v[i].str == v[i-1].str && v[i].status==0 && v[i-1].status==1)
        {
            mmap[v[i-1].str].push_back(v[i-1]);
            mmap[v[i].str].push_back(v[i]);
        }
    }

    map<string,vector<NODE>>::iterator iter;
    for( iter = mmap.begin() ; iter != mmap.end() ; iter++ )
    {
        cout<<iter->first;
        printf(" %02d\n",iter->second[0].month);

        double temp=0.0;
        for(int i=1;i<iter->second.size();i++,i++)
        {
            double total_price=bill(iter->second[i],price)-bill(iter->second[i-1],price);

            printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2lf\n",iter->second[i-1].day,iter->second[i-1].hour,iter->second[i-1].minute,iter->second[i].day,iter->second[i].hour,iter->second[i].minute,iter->second[i].sum_time-iter->second[i-1].sum_time,total_price);

            temp+=total_price;
        }
        printf("Total amount: $%.2lf\n",temp);
    }

    return 0;
}

lionの金库