题目描述
某公司需要对客户的计费数据进行处理。每个客户可能使用了多种服务,每种服务有一个计费因子(factor)和使用时长(time)。公司需要根据这些数据计算每个客户的总费用。
输入数据包括:
- 客户的计费数据,每条数据包含时间戳(times)、客户编号(cur)、计费因子(factor)和使用时长(t)。
- 计费因子到费用的映射表,每条数据包含计费因子(factor)和对应的费用(money)。
输出每个客户的总费用,格式为客户编号,总费用
。
输入描述
- 第一行:一个整数
n
,表示计费数据的条数。 - 接下来
n
行:每行包含一条计费数据,格式为times,cur,factor,t
,其中times
为时间戳,cur
为客户编号,factor
为计费因子,t
为使用时长。 - 第
n+2
行:一个整数m
,表示计费因子到费用的映射表的条数。 - 接下来
m
行:每行包含一条映射数据,格式为factor,money
,其中factor
为计费因子,money
为对应的费用。
输出描述
输出每个客户的总费用,格式为客户编号,总费用
。每个客户占一行。
用例输入
3
2023-03-01,client1,factor1,50
2023-03-01,client2,factor2,30
2023-03-02,client1,factor1,20
2
factor1,10
factor2,5
client1,700
client2,150
- 客户
client1
使用了factor1
服务,总时长为50 + 20 = 70
,费用为70 * 10 = 700
。 - 客户
client2
使用了factor2
服务,总时长为30
,费用为30 * 5 = 150
。
解题思路
-
数据结构:
- 使用
map<string, map<string, int>> mp
存储每个客户对每个计费因子的总使用时长。 - 使用
map<string, map<string, set<string>>> flag
标记每个时间戳和计费因子下已经记录过的客户,避免重复计费。 - 使用
map<string, int> datas
存储计费因子到费用的映射表。
- 使用
-
处理计费数据:
- 遍历每条计费数据,解析时间戳、客户编号、计费因子和使用时长。
- 如果使用时长在
0
到100
之间且该客户在当前时间戳和计费因子下未记录过,则将使用时长累加到mp
中。 - 将当前客户标记为已记录。
-
计算总费用:
- 遍历
mp
,计算每个客户的总费用。 - 使用
datas
中的计费因子到费用的映射表,计算每个计费因子的费用。 - 输出每个客户的总费用。
- 遍历
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<string>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include<set>
#include<list>
#include<sstream>
#include<bitset>
#include<stack>
#include<climits>
#include<iomanip>
#include<cstdint>
using namespace std;
map<string, map<string, int>> mp; // 存储每个客户对每个计费因子的总使用时长
map<string, map<string, set<string>>> flag; // 标记一个时间戳,一个计费因子的客户群
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
cin.ignore();
string input;
for (int i = 0; i < n; i++) {
getline(cin, input);
istringstream is(input);
string times, cur, factor;
int t;
getline(is, times, ',');
getline(is, cur, ',');
getline(is, factor, ',');
is >> t;
// 是在0-100之内的合法时长同时没记录过
if (t > 0 && t <= 100 && !flag[times][factor].count(cur)) {
mp[cur][factor] += t; // 累加使用时长
} else {
// 当作0处理,否则会漏客户 因为键没创建
mp[cur][factor] += 0;
}
flag[times][factor].insert(cur); // 标记当前客户
}
cin >> n;
cin.ignore();
map<string, int> datas; // 标识factor到money的映射
for (int i = 0; i < n; i++) {
getline(cin, input);
istringstream is(input);
string factor;
int money;
getline(is, factor, ',');
is >> money;
datas[factor] = money; // 存储计费因子到费用的映射
}
for (auto& t : mp) {
cout << t.first << ","; // 输出客户编号
// 遍历当前客户的所有服务
int all = 0;
for (auto c : t.second) {
if (datas.find(c.first) != datas.end()) {
all += datas[c.first] * c.second; // 计算总费用
}
}
cout << all << "\n"; // 输出总费用
}
return 0;
}