1016 Phone Bills (25分)
分析
将所有记录按照名字以及记录时间排序,将两条相邻的前后同名且前为on后为off的记录提取为一对用于计算通话时长的有效记录,并保存在map中对应的用户的记录中,最后遍历map计算每一对记录的时长、费用,以及总费用即可
注意时长以及费用的计算可以从00:00:00开始计算然后相减
代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
using namespace std;
int d[24], n, momo, dd, hh, mm;
string id, con;
map<string, int> mon;
struct node {
string iid;
int tim, condi;
node() {}
node(string dd, int tt, int cc) :iid(dd), tim(tt), condi(cc) {}
};
vector<node> rcd;
bool cmp(node a, node b) {
return (a.iid != b.iid) ? (a.iid < b.iid) : (a.tim < b.tim);
}
map<string, vector<pair<int, int> > >bill;
int getmoney(int t) {
int s = 0, i = 0;
while (t != 0) {
if (t >= 60) {
t -= 60;
s += 60 * d[i % 24];
}
else{
s += t * d[i % 24];
t = 0;
}
++i;
}
return s;
}
//另一种计算费用的方法
// int getmoney1(int t) {
// int s = 0, dd = t / (24 * 60), hh = t / 60 % 24, mm = t % 60, ss = 0;
// s += d[hh] * mm;
// for (int i = 0; i < 24; ++i)ss += d[i];
// s += ss * dd * 60;
// for (int i = 0; i < hh; ++i)
// s += d[i] * 60;
// return s;
// }
int main() {
for (int i = 0; i < 24; ++i)scanf("%d", &d[i]);
scanf("%d", &n);
while (--n >= 0) {
cin >> id;
scanf("%d:%d:%d:%d", &momo, &dd, &hh, &mm);
mon[id] = momo;
cin >> con;
rcd.push_back(node(id, mm+hh*60+dd*24*60, con[1] == 'n'));
}
sort(rcd.begin(), rcd.end(), cmp);
for (int i = 0; i < rcd.size() - 1; ++i)
if (rcd[i].iid == rcd[i + 1].iid && rcd[i].condi == 1 && rcd[i + 1].condi == 0)
bill[rcd[i].iid].push_back(pair<int, int>(rcd[i].tim, rcd[i + 1].tim));
for (auto it : bill) {
printf("%s %02d\n", it.first.c_str(), mon[it.first]);
double s = 0;
for (auto it1 : it.second) {
int a = getmoney(it1.first), b = getmoney(it1.second);
//int a = getmoney1(it1.first), b = getmoney1(it1.second);
double ss = (double)(b - a) / 100.0;
printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n", it1.first / (24 * 60), it1.first / 60 % 24, it1.first % 60, it1.second / (24 * 60), it1.second / 60 % 24, it1.second % 60, it1.second - it1.first, ss);
s += ss;
}
printf("Total amount: $%.2f\n", s);
}
return 0;
}