PTA甲级考试真题练习16——1016 Phone Bills

题目

在这里插入图片描述

生词生句

  1. A long-distance telephone company charges its customers by the following rules
    一个通信公司按照如下规则向用户收费
  2. Each on-line record is paired with the chronologically next record for the same customer provided it is an off-line record
    每一个在线记录都与下一条由相同用户产生的记录,前提是它是离线记录
  3. Any on-line records that are not paired with an off-line record are ignored, as are off-line records not paired with an on-line record.
    4任何不与离线记录配对的在线记录会被忽略,不与在线记录配对的离线记录也会被忽略

思路

模拟题/排序题,定义三个结构体,分别为记录结构体,用户信息结构体,以及输出信息结构体,然后都用set集合存储,因为set集合去重并有序,省去了排序的过程,然后算时间的费用参考日期处理。

坑点

  1. 没有花费的不输出

代码

#include <iostream>
#include<string.h>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<set>
using namespace std;
#define nmax 100  //一个用作示例的小顺序表的最大长度
typedef struct userRecord
{
	int time;    //天分时归一化后的时间,单位为分钟
	int on_line;  //为0时为挂断时间,为1时为接听时间
	bool operator < (const userRecord& record1) const
	{
		return time < record1.time;
	}
}userRecored;
typedef struct userInfo
{
	string name;
	int    month;  //月份
	bool operator < (const userInfo& user1) const
	{
		return name  < user1.name ;
	}
}userInfo;
typedef struct recordPair
{
	int minuteSum;
	int dayS, hourS , minuteS;
	int dayE, hourE, minuteE;
	double cost;
}recoredPair;
map<userInfo, set<userRecord>> user;
int usercost[nmax];
int day, hour, minute;
string isOnLine;
recordPair rp;
void Init()
{
	for (int i = 0; i < 24; ++i)
	{
		cin >> usercost[i];
	}
	int num;
	cin >> num;
	string s = "LLII";
	string s2 = "llii";
	if (s == s2)
	{
		cout << "111";
	}
	for (int i = 0; i < num; ++i)
	{
		userInfo info;
		userRecord Recored;
		cin >> info.name;
		scanf_s("%d:%d:%d:%d", &info.month, &day, &hour, &minute);
		cin >> isOnLine;
		Recored.time = day * 1440 + hour * 60 + minute;
		if (isOnLine == "on-line")
			Recored.on_line = 1;
		else if (isOnLine == "off-line")
			Recored.on_line = 0;
		//插入用户
		auto p = user.find(info);
		//如果没找到
		if (p == user.end())
		{
			set<userRecord> RecoredSet;
			RecoredSet.insert(Recored);
			user.insert(pair < userInfo, set<userRecord>>(info, RecoredSet));
		}
		else
		{
			p->second.insert(Recored);
		}
	}
}


double getCost(const int& timeS,const int& timeE)
{
	double cost = 0;
	int dayS, hourS, minuteS;
	int dayE, hourE, minuteE;
	rp.minuteSum = timeE - timeS;
	dayS = rp.dayS = timeS / 1440;
	hourS = rp.hourS = timeS % 1440 / 60;
	minuteS = rp.minuteS = timeS % 1440 % 60;
	dayE = rp.dayE = timeE / 1440;
	hourE = rp.hourE = timeE % 1440 / 60;
	minuteE = rp.minuteE = timeE % 1440 % 60;
	if (dayS == dayE && hourS == hourE)
		return (double)(minuteE - minuteS) * usercost[hourS]/100;
	cost += (double)usercost[hourS] * (60 - minuteS)/100;
	hourS++, minuteS = 0;
	if (hourS > 23)
	{
		hourS = 0;
		dayS++;
	}
	cost += (double)usercost[hourE] * minuteE/100;
	minuteE = 0;
	while (dayS < dayE || hourS < hourE)
	{
		cost += (double)usercost[hourS]*60/100;
		hourS++;
		if (hourS > 23)
		{
			dayS++;
			hourS = 0;
		}
	}
	return cost;
}

void dealRecord()
{
	for (auto &p : user)
	{
		vector<recordPair> vec;
		double cost_sum = 0;
		for (auto iter = p.second.begin(); iter != p.second.end(); ++iter)
		{
			auto iter_next = ++iter;
			--iter;
			if (iter_next != p.second.end() && iter->on_line == 1 && iter_next->on_line == 0)
			{
				rp.cost = getCost(iter->time, iter_next->time);
				vec.push_back(rp);
				cost_sum += rp.cost;
			}
		}
		if (cost_sum != 0)
		{
			cout << p.first.name << " ";
			printf("%.2d\n", p.first.month);
			for (auto& p : vec)
			{
				printf("%.2d:%.2d:%.2d ", p.dayS, p.hourS, p.minuteS);
				printf("%.2d:%.2d:%.2d %d $%.2lf\n", p.dayE, p.hourE, p.minuteE, p.minuteSum, p.cost);
			}
			printf("Total amount: $%.2lf\n", cost_sum);
		}
	}
}

int main()
{
	Init();
	dealRecord();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值