1016 Phone Bills (25point(s))
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
When we see this kind of problems, we need to have a good idea. We need to see the format of input and output, which is basically the structure Sorting and related problems. Next, we just need to take a look at the problems, and finally determine the scale of sorting and other functional requirements. Then we can use it with the dir ector and sort functions.
The requirements are as follows:
The first line will give you a 24-hour call rate,
The second line will tell you the number of next correspondence records
And then there's all the call logs
It is required to output call records and expenses (single call expenses and total call expenses of the person) by name
Attention:
- You can see clearly that the input of this problem cannot be underestimated, so in order to avoid the timeout caused by the input and output in some test cases, we should be careful to use scanf and printf for input and output.
Details:
First define the structure to define the format and content of the scattered call record. Through input, it is not difficult for us to determine each call record, including the name of the caller, the time record of one month, day, hour and minute, and the mark of the beginning or end of a call. Therefore, it is not difficult for us to determine the content of the structure:
typedef struct record{ string name; Time t; bool online; record(string na, int m, int d, int h, int mm, bool tag): name(na), t(m,d,h,mm), online(tag){} }record;
Of course, in order to reuse in the bill structure, an additional Time structure is defined here to assist the storage Time
typedef struct Time{ int day; int hour; int min; int month; Time(const Time &t): month(t.month), day(t.day), hour(t.hour), min(t.min){} Time(int m, int d, int h, int mm): month(m), day(d),hour(h),min(mm){} }Time;
According to the requirements of the topic, we have obtained scattered call records. Now we need to sort them by first name and then time
bool cmpRec(const record &a, const record &b){ if(a.name.compare(b.name)!=0) return (a.name< b.name); else if(a.t.month!=b.t.month) return (a.t.month<b.t.month); else if(a.t.day!=b.t.day) return (a.t.day<b.t.day); else if(a.t.hour!=b.t.hour) return (a.t.hour<b.t.hour); else return (a.t.min<b.t.min); }
sort(recordList.begin(),recordList.end(),cmpRec);
Then we select and arrange these scattered records. For the scattered records that have been arranged in the order of name and time, we only need to traverse them. We can match the records that are adjacent and the former is the beginning and the latter is the end, and make them into new bill records and put them into the container according to the difference of names.
Here we need to use a map class to complete the mapping of names and records
map<string, vector<bill> > billMap;//Here is a one to many mapping
Traverse selection and insert code as follows
for(int i=0;i<recordList.size()-1;i++){ if(recordList[i].name.compare(recordList[i+1].name)==0&&recordList[i].online==true&&recordList[i+1].online==false){ bill temp(recordList[i].name,recordList[i].t,recordList[i+1].t); billMap[recordList[i].name].push_back(temp); } }
Of course, when pairing, it is necessary to design a single call rate calculation problem.
At first, I was going to use the operation skills to realize it instead of adding up every minute. Later, I found that there were many holes, and I thought of the computer's 9 times per second operation rate. These addition operations really didn't need to be optimized. What's more, if it's in the examination room, it's better to pay attention to a fast and accurate way to directly realize the logic in daily life by code and algorithm, which is really not the case There's no way to be elegant:
bill(string na, Time t1, Time t2): name(na), t_1(t1), t_2(t2){ this->len=(t2.day-t1.day)*24*60+(t2.hour-t1.hour)*60+(t2.min-t1.min); int min=0; double amount=0.0; while (t1.day!=t2.day || t1.hour!=t2.hour || t1.min!=t2.min){ amount+=toll[t1.hour]; t1.min++; min++; if (t1.min==60){ t1.hour++; t1.min=0; } if (t1.hour==24){ t1.day++; t1.hour=0; } } this->cost=amount/100.00; }
At this stage, we have completed 90% of the work. At last, we just need to take out the name, calculate the total cost, and finally output
for(std::map< string , vector< bill > >::iterator it = billMap.begin();it!=billMap.end();it++){ cout<<it->first; vector<bill> billList = it->second; printf(" %02d\n", billList[0].t_1.month); double total=0; for(std::vector<bill>::iterator i = billList.begin();i!=billList.end();i++){ printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n", i->t_1.day, i->t_1.hour, i->t_1.min, i->t_2.day, i->t_2.hour, i->t_2.min, i->len, i->cost); total+=i->cost; } printf("Total amount: $%.2f\n", total); }
The complete code is as follows:
Code:
#include <bits/stdc++.h> using namespace std; int toll[24]; int recordNum; typedef struct Time{ int day; int hour; int min; int month; Time(const Time &t): month(t.month), day(t.day), hour(t.hour), min(t.min){} Time(int m, int d, int h, int mm): month(m), day(d),hour(h),min(mm){} }Time; typedef struct record{ string name; Time t; bool online; record(string na, int m, int d, int h, int mm, bool tag): name(na), t(m,d,h,mm), online(tag){} }record; bool cmpRec(const record &a, const record &b){ if(a.name.compare(b.name)!=0) return (a.name< b.name); else if(a.t.month!=b.t.month) return (a.t.month<b.t.month); else if(a.t.day!=b.t.day) return (a.t.day<b.t.day); else if(a.t.hour!=b.t.hour) return (a.t.hour<b.t.hour); else return (a.t.min<b.t.min); } typedef struct bill{ string name; Time t_1; Time t_2; int len; double cost; bill(string na, Time t1, Time t2): name(na), t_1(t1), t_2(t2){ this->len=(t2.day-t1.day)*24*60+(t2.hour-t1.hour)*60+(t2.min-t1.min); int min=0; double amount=0.0; while (t1.day!=t2.day || t1.hour!=t2.hour || t1.min!=t2.min){ amount+=toll[t1.hour]; t1.min++; min++; if (t1.min==60){ t1.hour++; t1.min=0; } if (t1.hour==24){ t1.day++; t1.hour=0; } } this->cost=amount/100.00; } }bill; vector<record> recordList; map<string, vector<bill> > billMap; int main(){ ///////////////////////////////////////////////read toll and recordNum for(int i=0;i<24;i++) scanf("%d", &toll[i]); scanf("%d", &recordNum); ///////////////////////////////////////////////read record for(int i=0;i<recordNum;i++){ string name, tag; int month, day, hour, min; bool online; cin>>name; scanf("%d:%d:%d:%d", &month, &day, &hour, &min); cin>>tag; if(tag=="on-line") online=true; else online=false; record temp(name, month, day, hour, min, online); recordList.push_back(temp); } ///////////////////////////////////////////////make records sorted and paired, and insert into bill sort(recordList.begin(),recordList.end(),cmpRec); for(int i=0;i<recordList.size()-1;i++){ if(recordList[i].name.compare(recordList[i+1].name)==0&&recordList[i].online==true&&recordList[i+1].online==false){ bill temp(recordList[i].name,recordList[i].t,recordList[i+1].t); billMap[recordList[i].name].push_back(temp); } } for(std::map< string , vector< bill > >::iterator it = billMap.begin();it!=billMap.end();it++){ cout<<it->first; vector<bill> billList = it->second; printf(" %02d\n", billList[0].t_1.month); double total=0; for(std::vector<bill>::iterator i = billList.begin();i!=billList.end();i++){ printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n", i->t_1.day, i->t_1.hour, i->t_1.min, i->t_2.day, i->t_2.hour, i->t_2.min, i->len, i->cost); total+=i->cost; } printf("Total amount: $%.2f\n", total); } return 0; }
Summary and harvest
(for my current level)
Map is an associated container of STL, which provides one-to-one data processing capability (the first can be called a keyword, each keyword can only appear once in the map, and the second may be called the value of the keyword). Due to this feature, it is possible to provide fast channels in programming when we process one-to-one data.