[ PAT-A ] 1016 Phone Bills (C++)

题目描述

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:
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


解题思路

题目大意
首先给定24个数,分别对应24小时不同时间段的电话费收费标准,另外给出N组数据,每组数据表示一个用户的通话开始或者结束的时间点,你所需要计算的是,每个用户在一个月内每次通话的时间段和通话费用,以及这个月的总话费
思路

  • 将输入的N组数据按每个用户分类存放好,那么需要用到结构体(用户名,开始/结束通话的时间,标志时间该是开始或结束)
  • 计算每个用户合理的通话时间段,并计算该时间段的通话费用,如果用户的所有时间点无法构成合理的时间段(如1月27日13:00开始通话,该日12:00结束,则不符合要求),则跳过该用户操作

代码设计
//结构体设计
//zhicheng
typedef struct {
    string name;
    vector<string> data;
    map<string,bool> fg;
}D;
map<string,int> ve;
vector<D> re;

[任务] 存放每个用户通话时间的状况
[说明] 如果该用户未被记录在册,首先将其记录在册,接下来直接给该用户增添一个时间(表示通话开始或结束)用map<string,int> ve表示记录用户的册子,vector<D> re存储每个用户通话数据
[接口]
void input(string na,string da,string flg,int& cnt)
输入: na 用户名 da 时间点(mm:dd:hh:mm) flg 开始通话或者结束通话 
         cnt 已存放用户数+1

//代码实现
//zhicheng
void input(string na,string da,string flg,int& cnt)
{
    D tmp;tmp.name=na;
    if(!ve[na]){re.push_back(tmp);ve[na]=cnt++;}//if it doesn't exit,we will creat the space for it
    re[ve[na]-1].data.push_back(da);//now,it already exits;
    if(flg!="off-line")re[ve[na]-1].fg[da]=true;
    else re[ve[na]-1].fg[da]=false;
}

[任务] 计算两个时间点(分别用字符串表示)相隔多少分钟,和这个时间段内的通话费用
[说明] 每个时间点的格式为mm:dd:hh:mm,对于相隔多少分钟对应量相减即可,计算通话费用,要考虑到两个时间点在同小时内,同一天,不同天三种情况.
[接口]
double op_time(string a,string b)
输入:a表示通话开始时间,b表示通话结束时间
输出: 返回这个时间段内的通话费用

//代码实现
//zhicheng
double op_time(string a,string b)
{
    double p=0;
    for(int i=0;i<24;i++) p+=60*rate[i];
    double pri=0;
    int time1[4]={0},time2[4]={0},cn=0;
    for(int i=0;i<a.length();i++) {if(a[i]==':'){cn++;i++;} time1[cn]=time1[cn]*10+a[i]-'0';}
    cn=0;
    for(int i=0;i<b.length();i++) {if(b[i]==':'){cn++;i++;} time2[cn]=time2[cn]*10+b[i]-'0';}
    printf("%02d:%02d:%02d %02d:%02d:%02d ",time1[1],time1[2],time1[3],time2[1],time2[2],time2[3]);
    printf("%d ",(time2[1]-time1[1])*24*60+(time2[2]-time1[2])*60+time2[3]-time1[3]);
    pri+=(time2[1]-time1[1])*p;//to prevent different days
    if(time2[2]>time1[2]) pri+=(60-time1[3])*rate[time1[2]]+time2[3]*rate[time2[2]];
    else if(time2[2]<time1[2])pri-=(60-time2[3])*rate[time2[2]]+time1[3]*rate[time1[2]];
    else pri+=(time2[3]-time1[3])*rate[time2[2]];
    for(int i=time1[2]+1;i<time2[2];i++) pri+=60*rate[i];
    for(int i=time2[2]+1;i<time1[2];i++) pri-=60*rate[i];
    return pri/100;
}


有关PAT (Basic Level) 的更多内容可以关注 ——> PAT-B题解


有关PAT (Advanced Level) 的更多内容可以关注 ——> PAT-A题解

铺子日常更新,如有错误请指正
传送门:代码链接 PTA题目链接 牛客网题目链接 PAT-A题解

猜你喜欢

转载自blog.csdn.net/S_zhicheng27/article/details/81364890
今日推荐