题意:
1. 先给了
24
24
个数表示
24
24
小时每个小时内通话的费用, 单位为 分/分钟
2. 给了
N(≤1000)
N
(
≤
1000
)
条记录,记录格式为 [姓名][月:日:小时:分钟][on/off-line], 表示这个人在这个时间开始/结束通话。对于同一个人,每个开始通话记录与在它之后时间最近的结束通话记录相匹配,结束通话记录同理,一对匹配构成一次通话,若没有匹配的则忽略。
3. 按照格式要求输出每个人的账单。
分析:按照题意模拟即可
坑点:
1. 每个人的账单的输出顺序按照字典序输出。
2. 每个人的账单内的通话记录需按照时间顺序输出。
3. 如果一个人的账单内没有通话记录,那他什么都不输出,直接跳过。
#include <bits/stdc++.h>
using namespace std;
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int MAXN = 1005;
const int MAXM = 100000 + 10;
struct record {
string name;
int mm, dd, hh, minute, type;
// 按照时间排序
bool operator<(const record &a) {
if (mm == a.mm)
{
if (dd == a.dd)
{
if (hh == a.hh)
{
return minute < a.minute;
}
else return hh < a.hh;
}
else return dd < a.dd;
}
else return mm < a.mm;
}
}R[MAXN];
struct Ans {
int dd_beg, hh_beg, mm_beg,
dd_end, hh_end, mm_end;
int amount_time;
int amount_fee;
Ans(int _dd_beg, int _hh_beg, int _mm_beg, int _dd_end, int _hh_end, int _mm_end,
int _amount_time, int _amount_fee)
{
dd_beg = _dd_beg, hh_beg = _hh_beg, mm_beg = _mm_beg;
dd_end = _dd_end, hh_end = _hh_end, mm_end = _mm_end;
amount_time = _amount_time, amount_fee = _amount_fee;
}
bool operator<(const Ans &a)
{
if (dd_beg == a.dd_beg)
{
if (hh_beg == a.hh_beg)
{
return mm_beg < a.mm_beg;
}
else return hh_beg < a.hh_beg;
}
else return dd_beg < a.dd_beg;
}
};
// vis 记录离当前 i 最近的名字值为 id 的那条记录的下标
int vis[MAXN];
int fee[30];
map<string, int>hsh;
vector<string>na;
vector<Ans>v[MAXN];
Ans calc(record bg, record ed) {
if (bg.dd != ed.dd)// 不在同一天内
{
int one_day = 0, amount_time = 0;
int amount_fee = 0;
for (int i = 0; i < 24; ++i)one_day += fee[i] * 60;
for (int i = bg.hh + 1; i < 24; ++i)amount_fee += fee[i] * 60, amount_time += 60;
amount_fee += (60 - bg.minute) * fee[bg.hh]; amount_time += (60 - bg.minute);
// 算一整天的
amount_fee += (ed.dd - bg.dd - 1) * one_day; amount_time += 24 * 60 * (ed.dd - bg.dd - 1);
for (int i = 0; i < ed.hh; ++i)amount_fee += fee[i] * 60, amount_time += 60;
amount_fee += ed.minute * fee[ed.hh]; amount_time += ed.minute;
return Ans(bg.dd, bg.hh, bg.minute, ed.dd, ed.hh, ed.minute, amount_time, amount_fee);
}
else //同一天内
{
int amount_time = 0;
int amount_fee = 0;
for (int i = bg.hh + 1; i < ed.hh; ++i)amount_fee += fee[i] * 60, amount_time += 60;
if (bg.hh == ed.hh) // 同一个小时内
{
amount_fee += (ed.minute - bg.minute) * fee[bg.hh];
amount_time += (ed.minute - bg.minute);
}
else
{
amount_fee += (60 - bg.minute) * fee[bg.hh]; amount_time += (60 - bg.minute);
amount_fee += ed.minute * fee[ed.hh]; amount_time += ed.minute;
}
return Ans(bg.dd, bg.hh, bg.minute, ed.dd, ed.hh, ed.minute, amount_time, amount_fee);
}
}
int main() {
memset(vis, 0, sizeof(vis));
for (int i = 0; i < 24; ++i)scanf("%d", &fee[i]);
int n, tot = 0; scanf("%d", &n);
string name, type;
for (int i = 1; i <= n; ++i)
{
cin >> name; scanf("%d:%d:%d:%d", &R[i].mm, &R[i].dd, &R[i].hh, &R[i].minute); cin >> type;
R[i].name = name; if (hsh.count(name) == 0)
{
hsh[name] = ++tot;
na.push_back(name);
}
if (type == "on-line")R[i].type = 0;
else R[i].type = 1;
}
sort(R + 1, R + n + 1);
sort(na.begin(), na.end());
for (int i = 1; i <= n; ++i)
{
int id = hsh[R[i].name];
if (R[i].type == 0)
{
vis[id] = i;
}
else if(vis[id] != 0 && R[i].type == 1)
{
v[id].push_back(calc(R[vis[id]], R[i]));
vis[id] = 0;
}
}
for (int i = 0; i < na.size(); ++i)
{
double total = 0;
int id = hsh[na[i]];
if (v[id].size() == 0)continue;
cout << na[i]; printf(" %02d\n", R[1].mm);
sort(v[id].begin(), v[id].end());
for (int j = 0; j < v[id].size(); ++j)
{
printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n"
, v[id][j].dd_beg, v[id][j].hh_beg, v[id][j].mm_beg
, v[id][j].dd_end, v[id][j].hh_end, v[id][j].mm_end
, v[id][j].amount_time, v[id][j].amount_fee / 100.0);
total += v[id][j].amount_fee / 100.0;
}
printf("Total amount: $%.2f\n", total);
}
}