PAT A 1016 Phone Bills (25 分)

本文详细介绍了如何设计和实现一个电话计费系统,通过使用C++编程语言和数据结构如map和vector,处理通话记录并计算费用。文章展示了具体的代码实现,包括数据预处理、通话记录排序和费用统计的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、题目概述&样例

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

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

二、思路

测试点1、2:仅输出有消费的用户;

STEP1:预处理

建立按ID索引的map结构即每个客户建立一个结构体, 结构体含:
{ 账单月份, 通话记录表:{ 时间, 标签(online/offline) } }

typedef struct
{
    int time, tag;
}item;
typedef struct
{
    int mon;
    vector<item> record;
}customer;
map<string, customer> rec;

其中时间不含月份, 转为分钟保存;

        rec[ID].mon = mon;
        temp.time = d * 24 * 60 + h * 60 + m;
        temp.tag = tag == "on-line" ? 0:1;
        rec[ID].record.push_back(temp);
STEP2:

由于map会自动依据ID排序, 所以直接按序遍历map;
先对该用户的通话记录按时间排序;
排序后,若有相邻记录,前一为online后一为offline,则是一条可用记录;
依次统计单次通话时长和话费;

    for( auto it = rec.begin(); it != rec.end(); ++it )//遍历
    {
        int sum = 0;//账单总和
        vector<item> temp = it->second.record;
        sort( temp.begin(), temp.end(), [] ( item a, item b ) { return a.time < b.time; } );//记录排序
        for( int i = 0; i < temp.size(); ++i )
        {
            if( i + 1 != temp.size() && temp[i].tag + 1 == temp[i + 1].tag )//可用记录
            {
                int toll = 0;
                if( !sum )
                {
                    cout << it->first;
                    printf(" %02d\n", it->second.mon);
                }
                printf("%02d:%02d:%02d %02d:%02d:%02d", temp[i].time / ( 24 * 60 ), ( temp[i].time / 60 ) % 24 , temp[i].time % 60, temp[i + 1].time / ( 24 * 60 ), ( temp[i + 1].time / 60 ) % 24 , temp[i + 1].time % 60);
                printf(" %d", temp[i + 1].time - temp[i].time);
                for( int j = temp[i].time; j < temp[i + 1].time; ++j )//话费统计
                {
                    toll += rate[ ( j / 60 ) % 24 ];
                }
                printf(" $%.2f\n", toll / 100.0);
                sum += toll;
                ++i;
            }
        }
        if( sum )
            printf("Total amount: $%.2f\n", sum / 100.0);
    }

话费统计:
从接通到挂断按分钟迭代累加, ( 时间 / 60 ) % 24可得到该分钟所在的小时,以便得到相应费率;

                for( int j = temp[i].time; j < temp[i + 1].time; ++j )
                {
                    toll += rate[ ( j / 60 ) % 24 ];
                }

三、代码

#include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct
{
    int time, tag;
}item;
typedef struct
{
    int mon;
    vector<item> record;
}customer;
int main()
{
    map<string, customer> rec;
    vector<int> rate(24);
    for( int i = 0; i < 24; ++i )
        scanf("%d", &rate[i]);
    int N;
    scanf("%d", &N);
    for( int i = 0, mon, d, h, m; i < N; ++i )
    {
        string ID, tag;
        item temp;
        cin >> ID;
        scanf("%d:%d:%d:%d", &mon, &d, &h, &m);
        cin >> tag;
        rec[ID].mon = mon;
        temp.time = d * 24 * 60 + h * 60 + m;
        temp.tag = tag == "on-line" ? 0:1;
        rec[ID].record.push_back(temp);
    }
    for( auto it = rec.begin(); it != rec.end(); ++it )
    {
        int sum = 0;
        vector<item> temp = it->second.record;
        sort( temp.begin(), temp.end(), [] ( item a, item b ) { return a.time < b.time; } );
        for( int i = 0; i < temp.size(); ++i )
        {
            if( i + 1 != temp.size() && temp[i].tag + 1 == temp[i + 1].tag )
            {
                int toll = 0;
                if( !sum )
                {
                    cout << it->first;
                    printf(" %02d\n", it->second.mon);
                }
                printf("%02d:%02d:%02d %02d:%02d:%02d", temp[i].time / ( 24 * 60 ), ( temp[i].time / 60 ) % 24 , temp[i].time % 60, temp[i + 1].time / ( 24 * 60 ), ( temp[i + 1].time / 60 ) % 24 , temp[i + 1].time % 60);
                printf(" %d", temp[i + 1].time - temp[i].time);
                for( int j = temp[i].time; j < temp[i + 1].time; ++j )
                {
                    toll += rate[ ( j / 60 ) % 24 ];
                }
                printf(" $%.2f\n", toll / 100.0);
                sum += toll;
                ++i;
            }
        }
        if( sum )
            printf("Total amount: $%.2f\n", sum / 100.0);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值