1016. Phone Bills (25)

本文详细阐述了如何通过算法匹配在线与离线记录,并计算从00:00:00到当前时间的耗费和分钟数。重点在于解决至少有一条匹配成功的记录问题,以及输出匹配成功的记录和其对应的成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.判断记录好坏,把所有记录以string存起来,按照字典序排序,相邻的两条记录满足要求:第一条为on-line且第二条为off-line,才是成功匹配;
2.采用计算00:00:00到现在的耗费和分钟数,这个方法比较简单

3.最重要的:题目中只强调至少有一条匹配成功的记录,不是说每个人都至少有一条匹配成功的记录,所以没有成功匹配记录的人不输出(主要卡在这)

/*
1.判断记录好坏,把所有记录以string存起来,按照字典序排序,相邻的两条记录满足要求:第一条为on-line且第二条为off-line,才是成功匹配;
2.采用计算00:00:00到现在的耗费和分钟数,这个方法比较简单
3.最重要的:题目中只强调至少有一条匹配成功的记录,不是说每个人都至少有一条匹配成功的记录,所以没有成功匹配记录的人不输出(主要卡在这)
*/
//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
struct customNode{
	string month;
	vector<string> online;
	vector<string> offline;
	vector<pair<string, string>> recordTag;
	vector<pair<string, string>> pairRecord;
	vector<pair<int, int>> eachCost;
	int total;
	customNode() :month(""), online(0), offline(0), eachCost(0), total(0){};
};
int str2int(string a){ return (a[0] - '0') * 10 + a[1] - '0'; }

int calculateCostFromZero(string a, vector<int>& rate)
{//计算从00:00:00到某个时间的耗费
	int rateSum = 0;//一天的总和
	for (int i = 0; i < 24; i++)
	{
		rateSum += rate[i] * 60;
	}
	int day = str2int(a.substr(3, 2));//天数
	int hour = str2int(a.substr(6, 2));//小时数
	int minute = str2int(a.substr(9, 2));//小时数
	int totalCost = day*rateSum;
	totalCost += minute*rate[hour];

	for (int i = 0; i < hour; i++)
	{
		totalCost += rate[i] * 60;
	}
	return totalCost;
}
int calculateMinutesFromZero(string a)
{//计算从00:00:00到某个时间的分钟数
	int day = str2int(a.substr(3, 2));//天数
	int hour = str2int(a.substr(6, 2));//小时数
	int minute = str2int(a.substr(9, 2));//小时数
	return day * 1440 + hour * 60 + minute;
}

pair<int, int> calculate(string a, string b, vector<int>& rate)
{//分别计算00:00:00和当前日期的差值

	int startCost = calculateCostFromZero(a, rate);
	int endCost = calculateCostFromZero(b, rate);
	int startMin = calculateMinutesFromZero(a);
	int endMin = calculateMinutesFromZero(b);

	return{ endCost - startCost, endMin - startMin };

}

pair<int, int> calculate2(string a, string b, vector<int>& rate)
{//计算差值的方法不是很好
	int startHour = str2int(a.substr(6, 2));//计算开始所在的小时
	int endHour = str2int(b.substr(6, 2));//计算结束时所在的小时
	int startNoDay = startHour * 60 + str2int(a.substr(9, 2));//计算H*60+m,单位为分钟
	int endNoDay = endHour * 60 + str2int(b.substr(9, 2));//计算H*60+m,单位为分钟

	int startWithDay = str2int(a.substr(3, 2)) * 1440 + startNoDay;//加上天数,单位为分钟
	int endWithDay = str2int(b.substr(3, 2)) * 1440 + endNoDay;//加上天数,单位为分钟
	int days = (endWithDay - startWithDay) / 1440;//查看隔了多少天
	int total = 0;
	for (int j = 0; j < days; j++)
	{//每多一天,都需要加上24小时的计费
		for (int i = 0; i < 24; i++)
			total += 60 * rate[i];
	}
	int recent = startNoDay;
	if (startNoDay > endNoDay)
	{
		endHour += 24;//如果起始的分钟数大于结束的分钟数,结束在第一天之后(有可能是2,3,4天),直接+24,便于统计
		endNoDay += 24 * 60;//No也需要加上24*60
	}
	for (int i = startHour + 1; i <= endHour && endHour != startHour; ++i)
	{//开始统计
		total += (i * 60 - recent)*rate[i - 1];
		recent = i * 60;
	}
	total += (endNoDay - recent)*rate[endHour];
	int diff = endWithDay - startWithDay;
	return{ total, diff };

}
bool cmpRecordTag(const pair<string, string>&a, const pair<string, string>&b)
{
	return a.first < b.first;
}
int main(void)
{

	vector<int> rate(48);// = { 10, 10, 10, 10, 10, 10, 20, 20, 20, 15, 15, 15, 15, 15, 15, 15, 20, 30, 20, 15, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 15, 15, 15, 15, 15, 15, 15, 20, 30, 20, 15, 15, 10, 10, 10 };
	//int rateSum = 0;
	//for (int i = 0; i < 24; i++)
	//{
	//	rateSum += rate[i]*60;
	//}
	//vector<pair<int, int>> temp(0);
	//temp.push_back(calculate("01:28:23:41", "01:28:23:42", rate));
	//temp.push_back(calculate("01:28:15:41", "01:28:16:05", rate));
	//temp.push_back(calculate("01:01:05:59", "01:01:07:00", rate));
	//temp.push_back(calculate("01:02:00:01", "01:04:23:59", rate));
	//temp.push_back(calculate("01:01:06:01", "01:01:08:03", rate));
	//
	for (int i = 0; i < 24; i++)
	{
		scanf("%d", &rate[i]);
		rate[i + 24] = rate[i];
	}
	int recordNum;
	cin >> recordNum;
	map<string, customNode> m;
	vector<string> nameList(0);
	for (int i = 0; i < recordNum; i++)
	{//输入各条记录
		string name, time, tag;
		cin >> name >> time >> tag;
		if (m.find(name) == m.end())
			nameList.push_back(name);

		m[name].recordTag.push_back({ time, tag });
	}

	//直接sort,则string就是按照字典序进行排列
	sort(nameList.begin(), nameList.end());

	for (int i = 0; i < nameList.size(); i++)
	{
		string name = nameList[i];
		sort(m[name].recordTag.begin(), m[name].recordTag.end(), cmpRecordTag);
		m[name].total = 0;
		for (int j = 0; j + 1< m[name].recordTag.size(); j++)
		{
			if (m[name].recordTag[j].second == "on-line"&&m[name].recordTag[j + 1].second == "off-line")
			{//当前记录为on-line,且下一条为off-line,则匹配成功
				m[name].pairRecord.push_back({ m[name].recordTag[j].first.substr(3), m[name].recordTag[j + 1].first.substr(3) });
				m[name].eachCost.push_back(calculate(m[name].recordTag[j].first, m[name].recordTag[j + 1].first, rate));
				m[name].total += m[name].eachCost.back().first;
			}
		}
		if (m[name].pairRecord.size() != 0)
		{//题目只确保至少有一条成功匹配的记录,但是没有说每个人至少有一条成功匹配的记录
			//没成功匹配记录的人就不输出
			cout << name << " " << m[name].recordTag[0].first.substr(0, 2) << endl;
			for (int j = 0; j < m[name].pairRecord.size(); j++)
			{
				cout << m[name].pairRecord[j].first << " " << m[name].pairRecord[j].second << " " << m[name].eachCost[j].second << " $";
				printf("%.2f", m[name].eachCost[j].first / 100.0);
				cout << endl;
			}
			printf("Total amount: $%.2f", m[name].total / 100.0);
			cout << endl;
		}

	}


	return 0;
}


优化这个sql SELECT count( 1 ) FROM ( SELECT B.ID, B.PURCHASE_REQUEST_ID, B.MATERIAL_ID, B.MATERIAL_CODE, B.MATERIAL_NAME, B.STANDARD, B.MODEL_ID, B.BILL_ROW_ID, B.BILL_NO, BILL_NAME, B.MODEL_CODE, B.MODEL_NAME, B.PARENT_MODEL_ID, B.PARENT_MODEL_CODE, B.PARENT_MODEL_NAME, B.UNIT_CODE, B.UNIT_NAME, B.PURCHASE_TYPE_CODE, CAST( NVL( B.APPLY_NUM, 0 ) AS NUMBER ( 24, 10 ) ) AS APPLY_NUM, CAST( NVL( B.DEAL_NUM, 0 ) AS NUMBER ( 24, 10 ) ) AS DEAL_NUM, CAST( NVL( B.RETURN_NUM, 0 ) AS NUMBER ( 24, 10 ) ) AS RETURN_NUM, B.DEAL_USER_ID, B.DEAL_USER_NAME, CAST( NVL( B.PRICE, 0 ) AS NUMBER ( 24, 10 ) ) AS PRICE, CAST( NVL( B.AMOUNT, 0 ) AS NUMBER ( 24, 10 ) ) AMOUNT, B.IMPLEMENT_CODE, B.IMPLEMENT_NAME, B.IMPLEMENT_INVEST_AMOUNT, B.PURCHASE_MANAGER_ID, B.PURCHASE_MANAGER_NAME, B.PROVIDER_ID, B.PROVIDER_NAME, B.REMARK, B.DELIVER_AREA, B.DELIVER_ADDRESS, B.RECEIVE_PEOPLE, B.RECEIVE_PEOPLE_PHONE, B.ITEM_STATUS, B.COST_CENTER, B.COST_BUDGET_CODE, B.COST_IMPLEMENT_NAME, B.FRAME_CONT_ID, B.FRAME_CONT_CODE, B.FRAME_CONT_NAME, B.DETAIL_CONFIG, B.PURCHASE_CATEGORY_CODE, B.INVOICE_TITLE_CODE, B.INVOICE_SEND_ADDRRSS, B.MATERIAL_REQUEST_ITEM_ID, B.YEAR, B.DELETE_FLAG, B.PROVINCE_CODE, B.REASON, B.PARENT_ITEM_ID, B.FRAME_CONT_ITEM_ID, B.SUB_MATERIAL_REQUEST_ID, B.SUB_MATERIAL_REQUEST_CODE, B.MATERIAL_URL, B.RECOMMEND_PROVIDER_NAMES, C.PURCHASE_REQUEST_CODE, C.PURCHASE_REQUEST_NAME, C.APPLY_TYPE_CODE, C.CREATOR_NAME, C.APPLY_TELEPHONE, C.COMPANY_NAME, C.DEPT_NAME, B.CREATE_TIME, TO_CHAR( B.CREATE_TIME, 'YYYY-MM-DD' ) CREATE_TIME_STR, C.ARRIVE_TIME, C.IS_TO_END, C.MONEY_WAY_CODE, C.OWN, C.APPLY_CATEGORY_CODE, C.manu_Type, C.BILL_ID, MMD.MATERIAL_TYPE_CODE, B.BRANCH_COMPANY_DEAL_USER_ID, B.BRANCH_COMPANY_DEAL_USER_NAME, ( SELECT ORG_NAME FROM ORGANIZATIONS WHERE DELETE_FLAG = '0' AND ORG_CODE = ( SELECT PARENT_COMPANY_NO FROM ORGANIZATIONS WHERE ID = B.MATERIAL_DEPT_ID )) AS MATERIAL_COMPANY_NAME, B.ORIGINAL, B.PROVIDER_PRODUCT_MODEL, B.PROVIDER_PRODUCT_NAME, B.PRODUCT_DESC, B.Back_Flag, CASE WHEN MMD.material_type_code = 'WZ' THEN '1' WHEN MMD.material_type_code = 'FW' THEN '2' ELSE '3' END apply_category_code_item, NVL( C.IS_CARDSYSTEM_REQUEST, '0' ) IS_CARDSYSTEM_REQUEST, B.APPLY_GROUP_AUTHORITES, B.SCIENTIFIC_RESEARCH_ID, B.SCIENTIFIC_RESEARCH_CODE, B.SCIENTIFIC_RESEARCH_NAME, B.PREQUALFY_CODE, nvl( C.IS_QUICK, '0' ) AS IS_QUICK, C.PURCHASE_WAY_CODE, C.PURCHASE_TYPE_CODE PURCHASE_TYPE_CODE_P, C.ORIGINAL_TYPE, C.PURCHASE_REQUEST_BILLS_TYPE, B.IS_FRAME_CONT_MONAD FROM PURCHASE_REQUEST_ITEM B LEFT JOIN PURCHASE_REQUEST C ON B.PURCHASE_REQUEST_ID = C.ID LEFT JOIN MATERIAL_DATA MMD ON MMD.ID = B.MATERIAL_ID AND MMD.DELETE_FLAG = '0' WHERE B.delete_flag = '0' AND B.Item_Status IN ( 1 ) AND NOT EXISTS ( SELECT * FROM purchase_request_item_log pril WHERE B.id = pril.purchase_request_item_id AND pril.lock_status = '1' AND pril.delete_flag = '0' ) AND ( ( c.apply_type_code NOT IN ( '20', '41', '3' ) AND nvl( B.Apply_Num, 0 ) > nvl( B.Deal_Num, 0 )) OR c.apply_type_code IN ( '20', '41', '3' ) ) AND B.Deal_User_Id =: 1 AND C.MONEY_WAY_CODE =: 2 AND C.APPLY_TYPE_CODE =: 3 AND C.PAY_OUT_TYPE_CODE =: 4 AND C.APPLY_CATEGORY_CODE =: 5 AND NVL( C.IS_CARDSYSTEM_REQUEST, '0' ) = : 6 AND NOT EXISTS ( SELECT * FROM purchase_request_item p left join material_province mp ON p.material_id = mp.material_id WHERE p.delete_flag = 0 AND mp.delete_flag = 0 AND mp.material_status = 03 AND mp.org_code = p.province_code AND p.id = B.id ) ORDER BY C.ID, B.ID ASC)
06-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值