每日一题——云服务计费问题

云服务计费问题(哈希表 + 排序)| 附详细 C源码解析

    • 一、题目描述
    • 二、输入描述
    • 三、输出描述
    • 四、样例输入输出
      • 输入示例:
      • 输出示例:
      • 说明:
    • 五、解题思路分析
    • 六、C实现源码详解(完整)
    • 七、复杂度分析

一、题目描述

云服务提供商会记录客户使用服务的计费日志。现在你需要根据这些日志为客户计算话单总费用。

日志记录包括:

  • 时间戳(长度为 10 的字符串)
  • 客户标识(长度为 1~16 的字符串)
  • 计费因子(长度为 1~16 的字符串)
  • 计费时长(整数范围为 0~100,超出视为非法并置为 0)

此外还提供一张计费因子单价表,未给出的因子视为单价为 0。

特殊规则

  • 同一客户 同一时间戳 同一计费因子 的记录只计一次,以首次记录为准。

你需要输出每个客户的总话单费用,并按客户标识的字典序升序输出。


二、输入描述

第一行:n 表示日志条数
接下来的 n 行:每行格式为 "时间戳,客户标识,计费因子,计费时长"
下一行:m 表示计费因子单价数
接下来 m 行:每行格式为 "计费因子,单价"

三、输出描述

每行一个客户,格式为:

客户名,总费用

按客户标识升序输出。


四、样例输入输出

输入示例:

5
1627845600,client1,factorA,10
1627845605,client2,factorB,15
1627845610,client1,factorA,5
1627845615,client1,factorB,8
1627845620,client2,factorB,20
2
factorA,5
factorB,7

输出示例:

client1,131
client2,245

说明:

  • client1:

    • factorA:10 + 5 = 15,单价 5 → 15×5=75
    • factorB:8,单价 7 → 8×7=56
    • 总计:75 + 56 = 131
  • client2:

    • factorB:15 + 20 = 35,单价 7 → 35×7 = 245

五、解题思路分析

  1. 去重处理:需要剔除重复记录,即:客户名 + 时间戳 + 计费因子 相同的记录只取第一个。
  2. 合法性检查:时长必须在 [0, 100] 范围,非法按 0 处理。
  3. 单价匹配:若找不到对应的计费因子,则按 0 处理。
  4. 客户费用计算:统计每个客户所有有效记录对应的费用总和。
  5. 排序输出:按客户名字典序升序输出。

六、C实现源码详解(完整)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_N 1000            // 日志最大数量
#define MAX_M 1000            // 计费因子最大数量
#define MAX_LEN 100           // ID 字符串最大长度
#define MAX_CLIENTS 1000      // 客户数量最大值
#define MAX_FACTORS 100       // 计费因子种类最大值// 客户记录结构体:包含客户ID、计费因子ID、累计使用时长
typedef struct {char client_id[MAX_LEN];      // 客户唯一标识char factor_id[MAX_LEN];      // 计费因子唯一标识int total_duration;           // 使用总时长
} ClientRecord;// 因子价格结构体:记录每个因子的价格
typedef struct {char factor_id[MAX_LEN];      // 因子IDint price;                    // 因子的单价
} FactorPrice;ClientRecord records[MAX_CLIENTS * MAX_FACTORS]; // 所有客户因子组合的记录
int record_count = 0;                             // 当前记录条数FactorPrice prices[MAX_FACTORS]; // 存储所有计费因子的价格
int price_count = 0;             // 当前因子数量// 根据客户ID和因子ID查找对应记录在数组中的索引位置,若不存在返回 -1
int find_record_index(const char* client_id, const char* factor_id) {for (int i = 0; i < record_count; i++) {if (strcmp(records[i].client_id, client_id) == 0 &&strcmp(records[i].factor_id, factor_id) == 0) {return i; // 找到返回索引}}return -1; // 未找到
}// 获取某个因子的单价,若找不到返回 0
int get_factor_price(const char* factor_id) {for (int i = 0; i < price_count; i++) {if (strcmp(prices[i].factor_id, factor_id) == 0) {return prices[i].price; // 返回对应单价}}return 0; // 未定义价格时按0处理
}int main() {int n;scanf("%d\n", &n); // 读取日志记录数(n 行)char line[200]; // 用于存储一行输入for (int i = 0; i < n; i++) {fgets(line, sizeof(line), stdin); // 读取一行日志数据// 分割字符串,依次提取日志ID、客户ID、因子ID、时长char* token = strtok(line, ",");char log_id[MAX_LEN], client_id[MAX_LEN], factor_id[MAX_LEN];int duration;strcpy(log_id, token); // 日志IDtoken = strtok(NULL, ",");strcpy(client_id, token); // 客户IDtoken = strtok(NULL, ",");strcpy(factor_id, token); // 因子IDtoken = strtok(NULL, ",");duration = atoi(token); // 时长// 若时长不合法(负值或超过100),设为0if (duration < 0 || duration > 100) duration = 0;// 查找该客户因子的记录int idx = find_record_index(client_id, factor_id);if (idx != -1) {// 已有记录,直接累计时长records[idx].total_duration += duration;} else {// 没有记录,新建一条strcpy(records[record_count].client_id, client_id);strcpy(records[record_count].factor_id, factor_id);records[record_count].total_duration = duration;record_count++; // 记录数加一}}int m;scanf("%d\n", &m); // 读取因子价格的条数for (int i = 0; i < m; i++) {fgets(line, sizeof(line), stdin); // 读取一行因子信息char* token = strtok(line, ",");strcpy(prices[i].factor_id, token); // 因子IDtoken = strtok(NULL, ",");prices[i].price = atoi(token);      // 对应价格price_count++;}// 用于记录已处理过的客户,防止重复统计char processed_clients[MAX_CLIENTS][MAX_LEN];int processed_count = 0;for (int i = 0; i < record_count; i++) {int already_processed = 0;// 判断该客户是否已经处理过for (int j = 0; j < processed_count; j++) {if (strcmp(processed_clients[j], records[i].client_id) == 0) {already_processed = 1;break;}}if (already_processed) continue; // 已处理,跳过// 标记为已处理strcpy(processed_clients[processed_count++], records[i].client_id);int total_cost = 0; // 该客户总费用// 累计该客户所有因子的费用for (int j = 0; j < record_count; j++) {if (strcmp(records[j].client_id, records[i].client_id) == 0) {int price = get_factor_price(records[j].factor_id);total_cost += records[j].total_duration * price;}}// 输出客户ID与其总费用printf("%s,%d\n", records[i].client_id, total_cost);}return 0; // 程序结束
}

七、复杂度分析

  • 时间复杂度
    • 去重处理 + 数据读取: O ( n ) O(n) O(n)
    • 因子价格映射: O ( m ) O(m) O(m)
    • 费用计算: O ( n ) O(n) O(n)
    • 排序输出: O ( k log ⁡ k ) O(k \log k) O(klogk)(k 为客户数)
  • 空间复杂度 O ( n + m ) O(n + m) O(n+m)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JVM】运行时数据区域

文章目录 1. 程序计数器补充 2. 虚拟机栈2.1 栈帧1. 局部变量表2. 操作数栈3. 动态链接4. 方法返回地址补充 3. 本地方法栈4. 堆5. 方法区静态常量池&#xff08;Class常量池&#xff09;运行时常量池字符串常量池&#xff08;1&#xff09;位置变化&#xff08;2&#xff09;放…

day28图像处理OpenCV

文章目录 一、图像预处理4 边缘填充4.1 边界复制&#xff08;BORDER_REPLICATE&#xff09;4.2 边界反射&#xff08;BORDER_REFLECT&#xff09;4.3 边界反射101&#xff08;BORDER_REFLECT_101&#xff09;4.4 边界常数&#xff08;BORDER_CONSTANT&#xff09;4.5 边界包裹&…

C++ Json-Rpc框架-3项目实现(2)

一.消息分发Dispatcher实现 Dispatcher 就是“消息分发中枢”&#xff1a;根据消息类型 MType&#xff0c;把消息派发给对应的处理函数&#xff08;Handler&#xff09;执行。 初版&#xff1a; #pragma once #include "net.hpp" #include "message.hpp"n…

C++算法优化实战:破解性能瓶颈,提升程序效率

C算法优化实战&#xff1a;破解性能瓶颈&#xff0c;提升程序效率 在现代软件开发中&#xff0c;算法优化是提升程序性能的关键手段之一。无论是在高频交易系统、实时游戏引擎&#xff0c;还是大数据处理平台&#xff0c;算法的高效性直接关系到整体系统的性能与响应速度。C作…

【PostgreSQL教程】PostgreSQL 特别篇之 语言接口连接PHP

博主介绍:✌全网粉丝22W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

山东大学软件学院创新项目实训开发日志(12)之将对话记录保存到数据库中

在之前的功能开发中&#xff0c;已经成功将deepseekAPI接口接入到springbootvue项目中&#xff0c;所以下一步的操作是将对话和消息记录保存到数据库中 在之前的开发日志中提到数据库建表&#xff0c;所以在此刻需要用到两个表&#xff0c;conversation表和message表&#xff…

Spring-注解编程

注解基础概念 1.什么是注解编程 指的是在类或者方法上加入特定的注解(XXX) 完成特定功能的开发 Component public classXXX{} 2.为什么要讲注解编程 1.注解开发方便 代码简洁 开发速度大大提高 2.Spring开发潮流 Spring2.x引入注解 Spring3.x完善注解 Springboot普及 推广注解…

Dify智能体平台源码二次开发笔记(5) - 多租户的SAAS版实现(2)

目录 前言 用户的查询 controller层 添加路由 service层 用户的添加 controller层 添加路由 service层-添加用户 service层-添加用户和租户关系 验证结果 结果 前言 完成租户添加功能后&#xff0c;下一步需要实现租户下的用户管理。基础功能包括&#xff1a;查询租…

基于若依的ruoyi-vue-plus的nbmade-boot在线表单的设计(一)架构方面的设计

希望大家一起能参与我的新开源项目nbmade-boot: 宁波智能制造低代码实训平台 主要目标是类似设计jeecgboot那样的online表单功能,因为online本身没有开源这部分代码,而我设计这个是完全开源的,所以希望大家支持支持,开源不容易。 1、数据库方面设计考虑 是在原来gen_table和…

WebFlux应用中获取x-www-form-urlencoded数据的六种方法

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

[Python基础速成]1-Python规范与核心语法

本系列旨在快速掌握Python&#xff0c;实现能够快速阅读和理解 Python 代码&#xff0c;并在可查阅语法的情况下进行 AI 学习。 本篇先了解一下Python基础知识。 本篇内容较菜鸟教程有所删减、方便快速构建大纲&#xff0c;且加入了PEP 8规范说明等有助于理解和编写代码的说明。…

农民剧团的春天与改变之路

杨天义&#xff0c;男&#xff0c;1966年9月生&#xff0c;中共党员&#xff0c;江西省吉安市吉水县水南农民剧团团长。 杨天义从废品收购起家&#xff0c;凭借自身的努力和奋斗&#xff0c;自筹资金100余万元建设了水南镇的第一座影剧院&#xff0c;组建了江西省吉安市吉水县…

python asyncio 的基本使用

1、引言 asyncio 是 Python 标准库中的一个库&#xff0c;提供了对异步 I/O 、事件循环、协程和任务等异步编程模型的支持。 asyncio 文档 2、进程、线程、协程 线程 线程是操作系统调度的基本单位&#xff0c;同一个进程中的多个线程共享相同的内存空间。线程之间的切换由操…

Leedcode刷题 | Day30_贪心算法04

一、学习任务 452. 用最少数量的箭引爆气球代码随想录435. 无重叠区间763. 划分字母区间 二、具体题目 1.452用最少数量的箭引爆气球452. 用最少数量的箭引爆气球 - 力扣&#xff08;LeetCode&#xff09; 在二维空间中有许多球形的气球。对于每个气球&#xff0c;提供的输…

Ant Design Vue 表格复杂数据合并单元格

Ant Design Vue 表格复杂数据合并单元格 官方合并效果 官方示例 表头只支持列合并&#xff0c;使用 column 里的 colSpan 进行设置。 表格支持行/列合并&#xff0c;使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时&#xff0c;设置的表格不会渲染。 <temp…

C++ 标准库中的 <algorithm> 头文件算法总结

C 常用 <algorithm> 算法概览 C 标准库中的 <algorithm> 头文件提供了大量有用的算法&#xff0c;主要用于操作容器&#xff08;如 vector, list, array 等&#xff09;。这些算法通常通过迭代器来操作容器元素。 1. 非修改序列操作 std::all_of, std::any_of, s…

程序化广告行业(84/89):4A广告代理公司与行业资质解读

程序化广告行业&#xff08;84/89&#xff09;&#xff1a;4A广告代理公司与行业资质解读 大家好&#xff01;在探索程序化广告行业的道路上&#xff0c;每一次知识的分享都是我们共同进步的阶梯。一直以来&#xff0c;我都希望能和大家携手前行&#xff0c;深入了解这个充满机…

deepin使用autokey添加微信快捷键一键显隐ctrl+alt+w

打开deepin商店&#xff0c;搜索快捷键&#xff0c;找到autokey 快捷键管理&#xff0c;点击安装 点击右键新建文件夹 点击右键新建脚本 打开脚本并添加以下内容 import subprocess import time# ------------------ 配置项 ------------------ WM_CLASS "wechat…

文件内容课堂总结

Spark SQL是Spark用于结构化数据处理的模块&#xff0c;前身是Shark。Shark基于Hive开发&#xff0c;虽提升了SQL-on-Hadoop效率&#xff0c;但对Hive依赖过多。2014年6月1日Shark项目停止开发&#xff0c;团队将资源投入Spark SQL项目。Spark SQL具有诸多优点&#xff0c;如摆…

Zotero PDF Translate 翻译插件使用OpenAI API配置教程

PDF Translate&#xff1a;提升 Zotero 内置 PDF 阅读器的翻译功能 “PDF Translate” 是一款为 Zotero 设计的插件&#xff0c;旨在方便用户在 Zotero 内置的 PDF 阅读器中进行划词或段落翻译&#xff0c;辅助阅读外文文献。 一、 安装插件 下载插件&#xff1a; 访问 PDF T…