机试题——云服务计费

题目描述

某公司需要对客户的计费数据进行处理。每个客户可能使用了多种服务,每种服务有一个计费因子(factor)和使用时长(time)。公司需要根据这些数据计算每个客户的总费用。

输入数据包括:

  1. 客户的计费数据,每条数据包含时间戳(times)、客户编号(cur)、计费因子(factor)和使用时长(t)。
  2. 计费因子到费用的映射表,每条数据包含计费因子(factor)和对应的费用(money)。

输出每个客户的总费用,格式为客户编号,总费用

输入描述

  1. 第一行:一个整数n,表示计费数据的条数。
  2. 接下来n行:每行包含一条计费数据,格式为times,cur,factor,t,其中times为时间戳,cur为客户编号,factor为计费因子,t为使用时长。
  3. n+2行:一个整数m,表示计费因子到费用的映射表的条数。
  4. 接下来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

解题思路

  1. 数据结构

    • 使用map<string, map<string, int>> mp存储每个客户对每个计费因子的总使用时长。
    • 使用map<string, map<string, set<string>>> flag标记每个时间戳和计费因子下已经记录过的客户,避免重复计费。
    • 使用map<string, int> datas存储计费因子到费用的映射表。
  2. 处理计费数据

    • 遍历每条计费数据,解析时间戳、客户编号、计费因子和使用时长。
    • 如果使用时长在0100之间且该客户在当前时间戳和计费因子下未记录过,则将使用时长累加到mp中。
    • 将当前客户标记为已记录。
  3. 计算总费用

    • 遍历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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值