Link

题意:

远程电话的收费是按照每分钟来计费的,现在告诉你一天24小时中每分钟的收费标准,以及n条通话记录,试求出每个人该月的消费账单。

只有开始记录没有结束记录的通话不计费,反之亦然。保证所有消费记录在同一个月,且至少含有一条满足计费的账单记录。

输出是需要输出用户姓名,月份,每一条记录的开始结束时间于计费,总计费。按照用户名升序输出账单。

思路:

常规的一个时间差计算题,但是该题细节较多,也有许多坑点。先按照用户名升序,再按照时间升序来排序。再依次处理每次完整的通话。

刚开始是考虑前缀和直接获取时间段对应的计费,但是已知过不了1、2测试点。

坑点:没有完整消费记录的用户不用输出账单,虽然我跳过了这个坑,但是为注意自己的”Total amount: $“是在判断以外输出的,这会导致无消费的账单同样有这句输出。

后来换了一个直接计算的思路,最后发现是输出的锅,哎~.

前缀和的代码:

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N = 6e5+10;int c[25];
int n, tt;
int s[N], pre[N];
string na, tmp, line, month;
map<string, int> vis;struct node{string name;string time;int tag;int tm;
}r[N];int get_int(char x){return x-'0';
}int trans(string s){int res = get_int(s[0])*10+get_int(s[1]);res *= 24;res += get_int(s[3])*10+get_int(s[4]);res *= 60;res += get_int(s[6])*10+get_int(s[7]);return res;
}bool cmp(node a, node b){if(a.name==b.name) return a.tm<b.tm;return a.name<b.name;
}signed main()
{for(int i = 0; i < 24; i ++){cin >> c[i];for(int j = 1; j <= 60; j ++){s[++tt] = c[i];pre[tt] = pre[tt-1]+c[i];}}cin >> n;for(int i = 1; i <= n; i ++){cin >> na >> tmp >> line;r[i].name = na;r[i].time = tmp.substr(3, 8);r[i].tm = trans(r[i].time);if(line[1]=='n') r[i].tag = 1;else r[i].tag = 2;if(month.size()==0) month = tmp.substr(0, 2);}sort(r+1, r+n+1, cmp);for(int i = 1; i <= n; i ++){if(!vis[r[i].name]){na = r[i].name;vis[na] ++;double tot = 0;bool flag = 0;for(int j = i; j < n; j ++){if(r[j].tag==1 && r[j+1].tag==2 && r[j+1].name==r[j].name){if(vis[r[j].name]==1){cout << na << " " << month << endl;vis[na] ++;}double cost = 0;int rep = get_int(r[j].time[0])*10+get_int(r[j].time[1]);rep *= 24*60;if(r[j].time.substr(0, 2) == r[j+1].time.substr(0,2)){cost = pre[r[j+1].tm-rep]-pre[r[j].tm-rep];}else{cost += pre[24*60]-pre[r[j].tm-rep];int days = stoi(r[j+1].time.substr(0,2))-stoi(r[j].time.substr(0, 2))-1;cost += days*pre[24*60];int rep1 = get_int(r[j+1].time[0])*10+get_int(r[j+1].time[1]);rep1 *= 24*60;cost += pre[r[j+1].tm-rep1];}tot += cost*0.01;cout << r[j].time << " " << r[j+1].time << " " << r[j+1].tm-r[j].tm << " $";cout << fixed << setprecision(2) << cost*0.01 << endl;flag = 1;}if(r[j+1].name!=na){i = j-1;break;}}if(flag) cout << "Total amount: $" << tot << endl;}}return 0;
}

直接计算的代码:

#include<bits/stdc++.h>
//#define int long long
#define endl '\n'
using namespace std;
const int N = 6e5+10;int c[25], sum;
int n, tt;
int s[N], pre[N];
string na, tmp, line, month;
map<string, int> vis;struct node{string name;string time;int tag;int tm;
}r[N];int get_int(char x){return x-'0';
}int trans(string s){int res = get_int(s[0])*10+get_int(s[1]);res *= 24;res += get_int(s[3])*10+get_int(s[4]);res *= 60;res += get_int(s[6])*10+get_int(s[7]);return res;
}bool cmp(node a, node b){if(a.name==b.name) return a.tm<b.tm;return a.name<b.name;
}int get_difference(string ed, string bg){int res = 0;int day0 = stoi(bg.substr(0,2)), day1 = stoi(ed.substr(0,2));int hour0 = stoi(bg.substr(3,2)), hour1 = stoi(ed.substr(3,2));int minute0 = stoi(bg.substr(6,2)), minute1 = stoi(ed.substr(6,2));if(day0==day1){  // 同一天
//        cout << "同一天" << endl;if(hour0==hour1){  // 同一小时res += (minute1-minute0)*c[hour0];
//            cout << "同一小时 -> res: " << res << endl;}else{  // 不同小时
//            cout << "不同小时:" << endl;res += (60-minute0)*c[hour0];
//            cout << "加上开始剩余分钟的 -> res: " << (60-minute0)*c[hour0] << endl;for(int i = hour0+1; i < hour1; i ++) res += 60*c[i];
//            cout << "加上中间小时的 -> res: " << res << endl;res += minute1*c[hour1];
//            cout << "加上结束剩余分钟的 -> res: " << res << endl;}}else{
//        cout << "不同天" << endl;res += (60-minute0)*c[hour0];
//        cout << "加上开始剩余分钟的 -> res: " << res << endl;for(int i = hour0+1; i < 24; i ++){  // 开始当天的消费res += 60*c[i];}
//        cout << "加上开始剩余小时的 -> res: " << res << endl;res += (day1-day0-1)*sum;  // 中间几天的消费
//        cout << "加上中间" << (hour1-hour0-1) << "天的 -> res: " << res << endl;for(int i = 0; i < hour1; i ++){res += 60*c[i];}
//        cout << "加上结束剩余小时的 -> res: " << res << endl;res += minute1*c[hour1];  // 结束当天的消费
//        cout << "加上结束剩余分钟的 -> res: " << res << endl;}return res;
}signed main()
{for(int i = 0; i < 24; i ++){cin >> c[i];sum += c[i]*60;}cin >> n;for(int i = 1; i <= n; i ++){cin >> na >> tmp >> line;r[i].name = na;r[i].time = tmp.substr(3, 8);r[i].tm = trans(r[i].time);if(line[1]=='n') r[i].tag = 1;else r[i].tag = 2;if(month.size()==0) month = tmp.substr(0, 2);}sort(r+1, r+n+1, cmp);for(int i = 1; i <= n; i ++){if(!vis[r[i].name]){na = r[i].name;vis[na] ++;double tot = 0;bool flag = 0;for(int j = i; j < n; j ++){if(r[j].tag==1 && r[j+1].tag==2 && r[j+1].name==r[j].name){if(vis[r[j].name]==1){cout << na << " " << month << endl;vis[na] ++;}double cost = get_difference(r[j+1].time, r[j].time);tot += cost*0.01;cout << r[j].time << " " << r[j+1].time << " " << r[j+1].tm-r[j].tm << " $";cout << fixed << setprecision(2) << cost*0.01 << endl;flag = 1;}if(r[j+1].name!=na){i = j-1;break;}}if(flag) cout << "Total amount: $" << tot << endl;}}return 0;
}

PAT甲级 1016 Phone Bills(时间差)相关推荐

  1. PAT甲级1016 Phone Bills :[C++题解]字符串处理(复杂题)(C语言格式化读入、输出很便利!!!)

    文章目录 题目分析 题目链接 题目分析 原题: 长途电话公司按以下规则向客户收费: 拨打长途电话每分钟要花费一定的费用,具体收费取决于拨打电话的时间. 客户开始拨打长途电话的时间将被记录,客户挂断电话 ...

  2. PAT甲级1016 (map,排序)

    题目 A long-distance telephone company charges its customers by the following rules: Making a long-dis ...

  3. PAT 甲级 1016

    读题: the rate structure, and the phone call records 24个价格,不同时间段内 (分/秒) 输出格式按照姓名和日期排序,开始编码没有注意到姓名排序,做了 ...

  4. PAT甲级真题目录(按题型整理)(转自柳神)

    转载自:https://www.liuchuo.net/archives/2502?tdsourcetag=s_pcqq_aiomsg 最短路径 1003. Emergency (25)-PAT甲级真 ...

  5. PAT甲级训练合集(1-70)

    本章题解跳转 考点 P1001 数字的数组表示和处理 P1002 多项式的数组表示和处理 P1003 深度优先搜素 P1004 深度优先搜素 P1005 哈希表 P1006 P1007 数组子区间求和 ...

  6. PAT 甲级-算法初步

    阅读原文 接上一篇 PAT 甲级-入门模拟 ,自我感觉这部分才是真正的算法入门,对基础的数据结构提供了很好的类型题进行匹配练习 包括分类:排序.散列.贪心.二分.双指针.打表.递推 排序 思想解释 排 ...

  7. 【PAT】PAT甲级题库所有题解(持续更新中...)

    题解: 本文为导航页,一些希望刷PAT甲级的玩家可以来看看,我会持续更新所有题目的题解(取决于我做到哪儿了(doge)) 题号按照PAT官网给出的标注 题目: 链接 标签 1001 A+B Forma ...

  8. PAT甲级1001~1025

    PAT甲级1001~1025 1001 A+B Format (20 分) 1002 A+B for Polynomials (25 分) 1003 Emergency (25 分) 1004 Cou ...

  9. PAT甲级题目翻译+答案 AcWing(字符串处理)

    1001 A+B Format (20 分) 题意 :将整数转换成标准格式 思路 :从后往前遍历字符串进行模拟,每三个数字加一个逗号,但不能是在最前面加逗号,也不能是加在负号后面 #include & ...

最新文章

  1. 二分查找模板全面总结
  2. CSS如何修改placeholder样式
  3. Spring JDBC数据库连接池设置
  4. 不该失去的,一块钱也不放弃
  5. 在 Windows 10 的 Linux 子系统(WSL)中运行 Kali
  6. 19.Delete Documents-官方文档摘录
  7. 95-32-015-ChannelPipeline-DefaultChannelPipeline
  8. python的科学计算库总结
  9. springboot多环境配置_编辑 SpringBoot|第五章:多环境配置
  10. 玩转 SpringBoot 2 快速整合 | FreeMarker篇
  11. Deformation Transfer for Triangle Meshes
  12. 白话SCRUM 之四:燃尽图
  13. Google搜索从入门到精通 v4.0
  14. Java程序员转行可以做什么?程序员
  15. Think Python 2e 中文版
  16. 3. lambda 方法引用
  17. 最新交易猫 闲鱼源码 带后台管理+个人码收款
  18. python基础课程讲解基本语法常见运算符以及结构语句
  19. 公安联勤指挥调度实战应用系统软件平台解决方案
  20. 20个最佳的flash游戏教程

热门文章

  1. 鸭子精进城 856
  2. Python 爬虫 数据提取
  3. 安全狗漏洞通告|Linux kernel越界写入漏洞解决方案
  4. 什么是 Android?
  5. JSON的parse()方法
  6. 第8章 对象引用、可变性和垃圾回收
  7. 在Devil的软件三角中管理成功; 项目,项目经理和开发人员
  8. 算法很美:01背包问题(动态规划、贪心)
  9. 2020-10-30
  10. postman 总结