计费时段计算
知识点 字符串 输入的读取解析 数组遍历
题目描述:电力公司的电费根据用电的时间,采用三挡计费:
第一档:用电时间在每天的12:00-13:30和17:30-18:00
第二档:每天从0:00起的,且不在第一档时段内的,累积的10小时
第三档: 其他时段
某设备每天开关机一次(0:00之前必然关机)。统计这台设备每天各个时段的开机时长,用分钟表示。
时间格式: HH:MM,24小时制
说明: 小时不足两位不补零,分钟严格保持两位。例如:8:08
输入:"HH:MM HH:MM",两个时间分别为设备开机时间、设备关机时间,中间空格间隔。例如:"8:00 23:30"。约束:
1.结束时间不超过0:00(最大为23:59),即不考虑跨天的情况。
2.如果开机时间跟关机时间相等,则认为是开机0分钟。例如:"8:00 8:00"
输出:整型数组,依次为第一、二、三档的时长,单位:分钟。例如:[120,600,210]
补充说明:无
---------------------
示例1
输入:"8:00 23:30"
输出:[120.600.210]
说明:第一档:12:00-13:30、17:30-18:00,共120分钟
第二档:8:00-12:00、13:30-17:30、18:00-20:00,共600分钟,达到10小时上限。其余的时间要归到第三档
第三档:20:00-23:30,共210分钟
示例2
输入:"13:00 17:45"
输出:[45,240,0]
说明:第一档:13:00-13:30、17:30-17:45,共45分钟
第二档:13:30-17:30,共240分钟
第三档:由于第二档还没达到10小时,第三档时间为0
------------------
问题分析
电力公司电费分三档计费:
- 第一档:12:00-13:30 和 17:30-18:00(固定时段)
- 第二档:设备开机时间内,除第一档外的时段,最多累计600分钟(10小时)
- 第三档:设备开机时间内,除第一档外,超过600分钟的部分
给定设备开机和关机时间(同一天内),计算各档位时长(分钟)。
解决思路
- 解析输入时间:将开机和关机时间转换为从0:00开始的分钟数。
- 计算第一档时长:检查开机时间段与两个第一档固定时段的重叠部分。
- 计算非第一档时长:总开机时长减去第一档时长。
- 计算第二档时长:非第一档时长不超过600分钟时,全部计入第二档;否则,第二档为600分钟。
- 计算第三档时长:非第一档时长超过600分钟时,超出部分为第三档。
代码实现(Python)
def calculate_electricity_cost(input_str): # 解析输入字符串 times = input_str.strip('"').split() start_str, end_str = times[0], times[1] # 将时间转换为分钟数 start_parts = start_str.split(':') end_parts = end_str.split(':') start_minute = int(start_parts[0]) * 60 + int(start_parts[1]) end_minute = int(end_parts[0]) * 60 + int(end_parts[1]) # 处理开机0分钟的情况 if start_minute == end_minute: return [0, 0, 0] # 第一档时段定义(分钟数) tier1_intervals = [ (12 * 60, 13 * 60 + 30), # 12:00-13:30 (17 * 60 + 30, 18 * 60) # 17:30-18:00 ] # 计算第一档重叠时长 first = 0 for interval in tier1_intervals: low = max(start_minute, interval[0]) high = min(end_minute, interval[1]) if low < high: first += high - low # 总开机时长 total_duration = end_minute - start_minute # 非第一档时长 non_first = total_duration - first # 第二档时长(不超过600分钟) second = min(non_first, 600) # 第三档时长(剩余部分) third = non_first - second return [first, second, third]代码实现(C++)
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; vector<int> calculateElectricityCost(string input) { // 解析输入字符串 size_t pos = input.find(' '); string start_str = input.substr(1, 5); string end_str = input.substr(pos + 1, 5); // 转换时间 int start_minute = stoi(start_str.substr(0, 2)) * 60 + stoi(start_str.substr(3, 2)); int end_minute = stoi(end_str.substr(0, 2)) * 60 + stoi(end_str.substr(3, 2)); // 处理0分钟情况 if (start_minute == end_minute) { return {0, 0, 0}; } // 第一档时段 vector<pair<int, int>> tier1_intervals = { {12*60, 13*60+30}, {17*60+30, 18*60} }; // 计算第一档时长 int first = 0; for (auto& interval : tier1_intervals) { int low = max(start_minute, interval.first); int high = min(end_minute, interval.second); if (low < high) { first += high - low; } } // 计算第二档和第三档 int total_duration = end_minute - start_minute; int non_first = total_duration - first; int second = min(non_first, 600); int third = non_first - second; return {first, second, third}; }代码实现(JavaScript)
function calculateElectricityCost(input) { // 解析输入字符串 const times = input.trim().split(' '); const startStr = times[0].replace('"', ''); const endStr = times[1].replace('"', ''); // 转换时间 const [startHour, startMinute] = startStr.split(':').map(Number); const [endHour, endMinute] = endStr.split(':').map(Number); const startTotal = startHour * 60 + startMinute; const endTotal = endHour * 60 + endMinute; // 处理0分钟情况 if (startTotal === endTotal) { return [0, 0, 0]; } // 第一档时段 const tier1Intervals = [ [12 * 60, 13 * 60 + 30], [17 * 60 + 30, 18 * 60] ]; // 计算第一档时长 let first = 0; for (const [start, end] of tier1Intervals) { const low = Math.max(startTotal, start); const high = Math.min(endTotal, end); if (low < high) { first += high - low; } } // 计算第二档和第三档 const totalDuration = endTotal - startTotal; const nonFirst = totalDuration - first; const second = Math.min(nonFirst, 600); const third = nonFirst - second; return [first, second, third]; }代码实现(Java)
import java.util.*; public class ElectricityCostCalculator { public static List<Integer> calculateElectricityCost(String input) { // 解析输入字符串 String[] times = input.replace("\"", "").split(" "); String startStr = times[0]; String endStr = times[1]; // 转换时间 String[] startParts = startStr.split(":"); String[] endParts = endStr.split(":"); int startMinute = Integer.parseInt(startParts[0]) * 60 + Integer.parseInt(startParts[1]); int endMinute = Integer.parseInt(endParts[0]) * 60 + Integer.parseInt(endParts[1]); // 处理0分钟情况 if (startMinute == endMinute) { return Arrays.asList(0, 0, 0); } // 第一档时段 int[][] tier1Intervals = { {12 * 60, 13 * 60 + 30}, {17 * 60 + 30, 18 * 60} }; // 计算第一档时长 int first = 0; for (int[] interval : tier1Intervals) { int low = Math.max(startMinute, interval[0]); int high = Math.min(endMinute, interval[1]); if (low < high) { first += high - low; } } // 计算第二档和第三档 int totalDuration = endMinute - startMinute; int nonFirst = totalDuration - first; int second = Math.min(nonFirst, 600); int third = nonFirst - second; return Arrays.asList(first, second, third); } }代码实现(Go)
package main import ( "fmt" "strconv" "strings" ) func calculateElectricityCost(input string) []int { // 解析输入字符串 trimmed := strings.Trim(input, "\"") times := strings.Split(trimmed, " ") startStr, endStr := times[0], times[1] // 转换时间 startParts := strings.Split(startStr, ":") endParts := strings.Split(endStr, ":") startHour, _ := strconv.Atoi(startParts[0]) startMin, _ := strconv.Atoi(startParts[1]) endHour, _ := strconv.Atoi(endParts[0]) endMin, _ := strconv.Atoi(endParts[1]) startTotal := startHour*60 + startMin endTotal := endHour*60 + endMin // 处理0分钟情况 if startTotal == endTotal { return []int{0, 0, 0} } // 第一档时段 tier1Intervals := [][2]int{ {12 * 60, 13*60 + 30}, {17*60 + 30, 18 * 60}, } // 计算第一档时长 first := 0 for _, interval := range tier1Intervals { low := max(startTotal, interval[0]) high := min(endTotal, interval[1]) if low < high { first += high - low } } // 计算第二档和第三档 totalDuration := endTotal - startTotal nonFirst := totalDuration - first second := nonFirst if second > 600 { second = 600 } third := nonFirst - second return []int{first, second, third} } func max(a, b int) int { if a > b { return a } return b } func min(a, b int) int { if a < b { return a } return b }测试示例
- 示例1:
"8:00 23:30"→ 第一档120分钟,第二档600分钟,第三档210分钟 →[120, 600, 210] - 示例2:
"13:00 17:45"→ 第一档45分钟,第二档240分钟,第三档0分钟 →[45, 240, 0]
以上实现严格遵循问题要求,确保各档位时长计算正确。