• PAT A1016 Phone Bills


    1016 Phone Bills

    分数 25

    作者 CHEN, Yue

    单位 浙江大学

    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.

    Input Specification:

    Each input file contains one test case. Each case has two parts: the rate structure, and the phone call records.

    The rate structure consists of a line with 24 non-negative integers denoting the toll (cents/minute) from 00:00 - 01:00, the toll from 01:00 - 02:00, and so on for each hour in the day.

    The next line contains a positive number N (≤1000), followed by N lines of records. Each phone call record consists of the name of the customer (string of up to 20 characters without space), the time and date (MM:dd:HH:mm), and the word on-line or off-line.

    For each test case, all dates will be within a single month. Each on-line record is paired with the chronologically next record for the same customer provided it is an off-line record. Any on-line records that are not paired with an off-line record are ignored, as are off-line records not paired with an on-line record. It is guaranteed that at least one call is well paired in the input. You may assume that no two records for the same customer have the same time. Times are recorded using a 24-hour clock.

    Output Specification:

    For each test case, you must print a phone bill for each customer.

    Bills must be printed in alphabetical order of customers' names. For each customer, first print in a line the name of the customer and the month of the bill in the format shown by the sample. Then for each time period of a call, print in one line the beginning and ending time and date (dd:HH:mm), the lasting time (in minute) and the charge of the call. The calls must be listed in chronological order. Finally, print the total charge for the month in the format shown by the sample.

    Sample Input:

    1. 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
    2. 10
    3. CYLL 01:01:06:01 on-line
    4. CYLL 01:28:16:05 off-line
    5. CYJJ 01:01:07:00 off-line
    6. CYLL 01:01:08:03 off-line
    7. CYJJ 01:01:05:59 on-line
    8. aaa 01:01:01:03 on-line
    9. aaa 01:02:00:01 on-line
    10. CYLL 01:28:15:41 on-line
    11. aaa 01:05:02:24 on-line
    12. aaa 01:04:23:59 off-line

    Sample Output:

    1. CYJJ 01
    2. 01:05:59 01:07:00 61 $12.10
    3. Total amount: $12.10
    4. CYLL 01
    5. 01:06:01 01:08:03 122 $24.40
    6. 28:15:41 28:16:05 24 $3.85
    7. Total amount: $28.25
    8. aaa 01
    9. 02:00:01 04:23:59 4318 $638.80
    10. Total amount: $638.80


     * 写得丑陋,还请见谅,这代码太繁琐了,我看着都想吐;
     * 总体思路是:先进行排序,以名字升序排序,再以时刻升序排序,这样排序保证每个人的
     * 信息是扎堆到一起的,并且是先接通电话,再挂断电话,即成对的接听电话与挂断电话是
     * 紧挨着的;
     *
     * 然后把成对的电话信息记录下来,最后把每个人一个月的总资费给统计出来,之后输出
     * 即可;
     *
     * 具体操作详看代码,有详细注释;
     *
     
    * 谨告自己: 看到题目不要怕,总是得下手去写,一直想,一直不敢下手,怎么能写得出
     * 来嘛,在进行处理信息的时候,就感觉很繁琐,一直很惧怕。后面也写了蛮长时间的,
     * 考试的时候遇到这种题该如何是好喔,我知道不是很难!!!!

     

    1. /**
    2. * 写得丑陋,还请见谅,这代码太繁琐了,我看着都想吐;
    3. * 总体思路是:先进行排序,以名字升序排序,再以时刻升序排序,这样排序保证每个人的
    4. * 信息是扎堆到一起的,并且是先接通电话,再挂断电话,即成对的接听电话与挂断电话是
    5. * 紧挨着的;
    6. *
    7. * 然后把成对的电话信息记录下来,最后把每个人一个月的总资费给统计出来,之后输出
    8. * 即可;
    9. *
    10. * 具体操作详看代码,有详细注释;
    11. *
    12. * 谨告自己: 看到题目不要怕,总是得下手去写,一直想,一直不敢下手,怎么能写得出
    13. * 来嘛,在进行处理信息的时候,就感觉很繁琐,一直很惧怕。后面也写了蛮长时间的,
    14. * 考试的时候遇到这种题该如何是好喔,我知道不是很难!!!!
    15. */
    16. #include <iostream>
    17. #include <cstring>
    18. #include <algorithm>
    19. #include <map>
    20. #include <vector>
    21. using namespace std;
    22. const int N = 1010;
    23. //记录输入的信息
    24. struct Infor
    25. {
    26. //名字,通话时刻,state表示接听电话还是挂断电话
    27. string name,tim,state;
    28. //先以名字进行升序,名字相同,再以通话时刻进行升序
    29. bool operator < (const Infor & a) const
    30. {
    31. if(name != a.name)
    32. return name < a.name;
    33. else
    34. return tim < a.tim;
    35. }
    36. }s[N];
    37. double w[25];
    38. int n;
    39. //存储处理后的成对的每个人的接通与挂断电话的信息
    40. struct Node
    41. {
    42. //名字,接听时刻,挂断时刻
    43. string name, sta_tim, end_tim;
    44. //此电话接通时长
    45. int stim;
    46. //资费
    47. double sum;
    48. };
    49. //res存储处理后的成对的每个人的接通与挂断电话的信息
    50. vector<Node> res;
    51. //mp存储每个人在这个月内总共所需的电话费是多少
    52. map<string,double> mp;
    53. void deal()
    54. {
    55. for(int i=0; i<n; ++i)
    56. {
    57. //如果i == n-1 ,那么毕然不存在成对的接通与挂断电话,不进行处理
    58. if(i == n-1)
    59. continue;
    60. //如果不存在成对的接通与挂断电话,不进行处理
    61. if(s[i].name != s[i+1].name || s[i].state != "on-line" || s[i+1].state != "off-line")
    62. continue;
    63. double sum = 0; //这次通话的资费
    64. int stime = 0; //这此次通话的总时间
    65. int flag = 1;
    66. string a = s[i].tim.substr(3, 2), b = s[i].tim.substr(6,2),
    67. c = s[i].tim.substr(9,2), d = s[i+1].tim.substr(3, 2) ,
    68. e = s[i+1].tim.substr(6,2), f = s[i+1].tim.substr(9,2);
    69. //将字符串时刻转化为整型的时分秒
    70. int d1 = stoi(a), h1 = stoi(b), m1 = stoi(c);
    71. int d2 = stoi(d), h2 = stoi(e), m2 = stoi(f);
    72. //总的来说就是把两个时间以小时划分,分为第一个时间段,中间时间段,最后时间段
    73. while(1)
    74. {
    75. //最后一个时间段了
    76. if(d1 == d2 && h1 == h2)
    77. {
    78. int v = m2 - m1;
    79. stime += v;
    80. sum += v*w[h1]*0.01;
    81. break;
    82. }
    83. else
    84. {
    85. //第一个时间段
    86. if(flag == 1)
    87. {
    88. int v = 60 - m1;
    89. sum += v*w[h1] * 0.01;
    90. stime += v;
    91. m1 = 0;
    92. h1++;
    93. flag = 0;
    94. }
    95. //中间时间段
    96. else
    97. {
    98. sum += 60*w[h1] * 0.01;
    99. stime += 60;
    100. h1++;
    101. }
    102. }
    103. if(h1 == 24) //这儿得处理一下
    104. {
    105. d1++;
    106. h1 = 0;
    107. }
    108. }
    109. //成对的信息进行存储到res中
    110. res.push_back({s[i].name, s[i].tim, s[i+1].tim, stime, sum});
    111. }
    112. //最后处理一下,将每个人的资费进行统计存储
    113. double sum = 0;
    114. for(int i=0;i<res.size();++i)
    115. {
    116. sum += res[i].sum;
    117. if(i == res.size()-1 || res[i].name != res[i+1].name)
    118. {
    119. mp[res[i].name] = sum;
    120. sum = 0;
    121. }
    122. }
    123. }
    124. void Print()
    125. {
    126. for(int i=0;i<res.size();++i)
    127. {
    128. //第一个人名特判一下
    129. if(i == 0)
    130. cout << res[i].name << ' ' << res[i].sta_tim.substr(0,2) << endl;
    131. printf("%s %s %d $%.2f\n",res[i].sta_tim.substr(3).c_str(),
    132. res[i].end_tim.substr(3).c_str(), res[i].stim, res[i].sum);
    133. //中间的人民与总资费直接输出
    134. if(i < res.size()-1 && res[i].name != res[i+1].name)
    135. {
    136. printf("Total amount: $%.2f\n", mp[res[i].name]);
    137. cout << res[i+1].name << ' ' << res[i+1].sta_tim.substr(0,2) << endl;
    138. }
    139. //最后一个总资费特判一下
    140. if(i == res.size()-1)
    141. printf("Total amount: $%.2f\n", mp[res[i].name]);
    142. }
    143. }
    144. int main()
    145. {
    146. for(int i=0; i<24; ++i)
    147. cin >> w[i];
    148. cin >> n;
    149. for(int i=0; i<n; ++i)
    150. cin >> s[i].name >> s[i].tim >> s[i].state;
    151. sort(s, s+n);
    152. deal();
    153. Print();
    154. return 0;
    155. }

  • 相关阅读:
    对CU50的修改(未使用)
    3分钟搞懂oled透明触摸显示屏
    (十一)PostgreSQL的wal日志(2)-默认wal日志大小
    《前端框架开发技术》HTML+CSS+JavaScript 制作个人简历模板
    throw抛出异常后的代码执行情况
    基于PostGIS实现大量不相邻多边形的外轮廓提取
    cloudera server与agent失连问题
    Java ~ Executor ~ ScheduledExecutorService【总结】
    TailwindCSS使用并开启JIT(vue2)
    面试算法常考题之-------逆波兰式合集
  • 原文地址:https://blog.csdn.net/qq_51825761/article/details/127874712