电话账单
1. 题目地址
https://www.acwing.com/problem/content/1495/
2. 题目解析
这道题的题意非常复杂,具体可以归结为:
1. 需要接收各时间段的话费信息,这里可以使用数组接收
2. 需要一个结构体来存储记录的信息:格式化时间(便于日后的输出),由时间所转换过来的分钟数(这里主要方便记录之间的排序和计算花费),该记录的状态。(用于匹配,判断该记录是否合法)
3. 由于需要按照字典序输出该用户的账单信息。因此使用map来存储:key:用户名 value:该用户的通话记录.map是天然有序的,内部为红黑树。因此:key(用户名)自动按照字典序排列。
4. 需要使用前缀和算法来预处理:某月1日0点0分开始到某分钟所需要的总花费。当需要求从S分钟开始到E分钟结束这一时间段的花费时,我们就可以使用公式:sum[E] - sum[S]; 代表:某月1日0点0分开始到E分钟所需要的总花费 - 某月1日0点0分开始到S分钟所需要的总花费。这样就求得了S分钟开始到E分钟所需要的总花费。
5. 美分到美元需要进行转换:1美元 = 100美分。
6. 总花费应为浮点数,并且需要保留两位小数。
7. 需要熟练运用:sprintf,c_str,运算符重载,格式化输入等知识点。
3. 题解
这里直接按照上述的解析做就行。唯一需要注意的就是:
1. 细节。
2. 前缀和算法。如果忘记,请参考之前博客。
4. 代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
const int N = 1010;
const int M = 31*1440 + 10;
struct Record{
int minutes;
string status;
string format_time;
bool operator<(const Record& c){
return minutes < c.minutes;
}
};
map<string,vector<struct Record>> persons;
double sum[M];
int cost[24];
char name[20],status[20];
int month,day,hour,minute;
int main(){
int n;
for(int i = 0;i < 24;i ++){
scanf("%d",&cost[i]);
}
for(int i = 1;i < M; i ++){
sum[i] = sum[i-1] + cost[(i - 1) % 1440 / 60] / 100.0;
}
scanf("%d",&n);
for(int i = 0;i < n;i ++){
scanf("%s %d:%d:%d:%d %s",name,&month,&day,&hour,&minute,status);
char format_time[20];
sprintf(format_time,"%02d:%02d:%02d",day,hour,minute);
int minutes = (day - 1) * 1440 + hour * 60 + minute;
persons[name].push_back({minutes,status,format_time});
}
for(auto person : persons){
string name = person.first;
auto records = person.second;
double total = 0;
sort(records.begin(),records.end());
for(int i = 0; i + 1 < records.size(); i ++){
if(records[i].status == "on-line" && records[i+1].status == "off-line"){
if(!total){
printf("%s %02d\n",name.c_str(),month);
}
int minutes = records[i+1].minutes - records[i].minutes;
double money = sum[records[i+1].minutes] - sum[records[i].minutes];
total += money;
printf("%s %s %d $%.2lf\n",records[i].format_time.c_str(),records[i+1].format_time.c_str(),minutes,money);
}
}
if(total){
printf("Total amount: $%.2lf\n",total);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现