A1016 Phone Bills

摘要
Title: A1016 Phone Bills
Tag: 字符串、sprintf
Memory Limit: 64 MB
Time Limit: 1000 ms

Powered by:NEFU AB-IN

Link

A1016 Phone Bills

  • 题意

    A long-distance telephone company charges its customers by the following rules:
    Making a long-distance call costs a certain amount per minute, depending on the time of day when the call is made. When a customer starts connecting a long-distance call, the time will be recorded, and so will be the time when the customer hangs up the phone. Every calendar month, a bill is sent to the customer for each minute called (at a rate determined by the time of day). Your job is to prepare the bills for each month, given a set of phone call records.

  • 思路

    大模拟,部分见代码注释
    整体思路:

    • 先处理这一个月,到达的每一分钟花费的前缀和,这样方便O(1)查询
    • 读入数据,每个人的record按时间排序,只有online和offline前后连接的两个record才有效

    注:

    • sprintf 格式化输入字符数组,如sprintf(format_time, "%02d:%02d:%02d", day, hour, minute);
    • char[], char* 转换为string,直接赋值即可,如char[] a; string x = a
  • 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    /*
    * @Author: NEFU AB-IN
    * @Date: 2023-01-04 10:54:05
    * @FilePath: \GPLT\A1016\A1016.cpp
    * @LastEditTime: 2023-01-04 11:17:33
    */
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <map>
    #include <vector>

    using namespace std;

    const int N = 1010, M = 31 * 1440 + 10;

    int n;
    int cost[24];
    double sum[M]; // 存储一个月内所有分钟数的前缀和

    struct records
    {
    int minutes; // 把时间转换为分钟
    string state; // on-line or off-line
    string format_time; // 格式化时间

    bool operator<(const records &t) const
    {
    return minutes < t.minutes;
    }
    };

    map<string, vector<records>> persons;

    int main()
    {

    for (int i = 0; i < 24; i++)
    cin >> cost[i];

    // 计算一个月内所有分钟数对应的钱数
    for (int i = 0; i < M; i++)
    sum[i] = sum[i - 1] + cost[(i - 1) % 1440 / 60] / 100.0; // 减1,算前一个时刻所在分段

    cin >> n;

    // 读入数据
    char name[50], state[10], format_time[20];
    int month, day, hour, minute;
    for (int i = 0; i < n; i++)
    {
    scanf("%s %d:%d:%d:%d %s", name, &month, &day, &hour, &minute, state);

    int minutes = day * 1440 + hour * 60 + minute;

    sprintf(format_time, "%02d:%02d:%02d", day, hour, minute); // 格式化字符串

    persons[name].push_back({minutes, state, format_time});
    }

    for (auto &person : persons)
    {
    auto name = person.first;
    auto record = person.second;
    sort(record.begin(), record.end());

    // 然后开始找,一前一后是on和off对应的计算时间和话费
    double total_money = 0; // 总的钱数
    double each_money = 0;
    for (int i = 0; i + 1 < record.size(); i++)
    {
    auto a = record[i], b = record[i + 1];

    if (a.state == "on-line" && b.state == "off-line")
    {
    // 钱为0时,输出这个人名和月份
    if (!total_money)
    printf("%s %02d\n", name.c_str(), month); // c_str()用来转成字符串

    cout << a.format_time << ' ' << b.format_time;

    each_money = sum[b.minutes] - sum[a.minutes]; // 不算a的钱
    printf(" %d $%.2lf\n", b.minutes - a.minutes, each_money);

    total_money += each_money;
    }
    }

    if (total_money)
    printf("Total amount: $%.2lf\n", total_money);
    }

    return 0;
    }
使用搜索:谷歌必应百度