计费时段计算
华为OD机试真题 华为OD上机考试真题 4月22号 100分题型
华为OD机试真题目录点击查看: 华为OD机试真题题库目录|机考题库 + 算法考点详解
题目描述
电力公司的电费根据用电的时间,采用三挡计费:
- 第一档:用电时间在每天的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”。
约束:
- 结束时间不超过0:00(最大为23:59),即不考虑跨天的情况。
- 如果开机时间跟关机时间相等,则认为是开机0分钟。例如:“8:00 8:00”
输出描述
依次为第一、二、三档的时长,单位:分钟
用例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
题解
思路:模拟
- 首先将开始时间和结束时间以及题目要求的第一档时间补全转换为分钟表示。
- 总用电时间为
total = end - time, 如果total ==0则直接返回[0,0,0]即可 - 对于第一档时间主要看用电时间为
12:00-13:30和17:30-18:00交集,两个时间段存在交集的有个公式,例如{start1, end1}, {start2, end2}的存在交集的情况为min(end1, end2) - max(start1, start2) > 0,其大小就为上述计算公式。利用这个可以求出第一档所用时间。 - 第二档所用时间为
min(total - 第一档时间, 10 * 60) - 第三档所用时间为
total - 第一档时间 - 第二档时间
c++
#include<iostream> #include<vector> #include<string> #include <utility> #include <sstream> #include<algorithm> #include<cmath> #include<map> using namespace std; // 通用 切割函数 函数 将字符串str根据delimiter进行切割 vector<string> split(const string& str, const string& delimiter) { vector<string> result; size_t start = 0; size_t end = str.find(delimiter); while (end != string::npos) { result.push_back(str.substr(start, end - start)); start = end + delimiter.length(); end = str.find(delimiter, start); } // 添加最后一个部分 result.push_back(str.substr(start)); return result; } // 同一使用分钟表示 int getTimeInt(string time) { vector<string> timeSplit = split(time, ":"); int res = 0; res = stoi(timeSplit[0]) * 60 + stoi(timeSplit[1]); return res; } vector<int> calBilling(string& startEnd) { vector<int> res(3, 0); vector<string> timeSplit = split(startEnd, " "); string start = timeSplit[0]; string end = timeSplit[1]; int startTimeMinute = getTimeInt(start); int endTimeMinute = getTimeInt(end); // 结果都为0,直接返回 if (endTimeMinute == startTimeMinute ) { return res; } int totalTime = endTimeMinute - startTimeMinute; // 计算第一档交集 if (min(endTimeMinute, getTimeInt("13:30")) - max(startTimeMinute, getTimeInt("12:00")) > 0) { res[0] += min(endTimeMinute, getTimeInt("13:30")) - max(startTimeMinute, getTimeInt("12:00")); } if (min(endTimeMinute, getTimeInt("18:00")) - max(startTimeMinute, getTimeInt("17:30")) > 0) { res[0] += min(endTimeMinute, getTimeInt("18:00")) - max(startTimeMinute, getTimeInt("17:30")); } // 剩余总时间减去第一档 totalTime -= res[0]; if (totalTime == 0) { return res; } // 第二档 res[1] = min(totalTime, 10 * 60); totalTime -= res[1]; //第三档为剩余时间 res[2] = totalTime; return res; } int main() { string input; getline(cin, input); vector<int> res = calBilling(input); // 输出结果 for (int i = 0; i < 3; i++) { cout << res[i]; if (i != 2) { cout << ","; } } return 0; }JAVA
import java.util.*; public class Main { // 时间转分钟 public static int getTimeInt(String time) { String[] parts = time.split(":"); return Integer.parseInt(parts[0]) * 60 + Integer.parseInt(parts[1]); } public static int[] calBilling(String startEnd) { int[] res = new int[3]; String[] timeSplit = startEnd.split(" "); String start = timeSplit[0]; String end = timeSplit[1]; int startTime = getTimeInt(start); int endTime = getTimeInt(end); // 无时间 if (startTime == endTime) return res; int totalTime = endTime - startTime; // 第一档区间 12:00 - 13:30 int l1 = Math.max(startTime, getTimeInt("12:00")); int r1 = Math.min(endTime, getTimeInt("13:30")); if (r1 > l1) res[0] += (r1 - l1); // 第一档区间 17:30 - 18:00 int l2 = Math.max(startTime, getTimeInt("17:30")); int r2 = Math.min(endTime, getTimeInt("18:00")); if (r2 > l2) res[0] += (r2 - l2); totalTime -= res[0]; if (totalTime == 0) return res; // 第二档 res[1] = Math.min(totalTime, 10 * 60); totalTime -= res[1]; // 第三档 res[2] = totalTime; return res; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); String input = sc.nextLine(); int[] res = calBilling(input); System.out.println(res[0] + "," + res[1] + "," + res[2]); } }Python
importsys# 时间转分钟defget_time_int(time):h,m=map(int,time.split(":"))returnh*60+mdefcal_billing(start_end):res=[0,0,0]start,end=start_end.split()start_time=get_time_int(start)end_time=get_time_int(end)ifstart_time==end_time:returnres total_time=end_time-start_time# 第一档:12:00 - 13:30l=max(start_time,get_time_int("12:00"))r=min(end_time,get_time_int("13:30"))ifr>l:res[0]+=r-l# 第一档:17:30 - 18:00l=max(start_time,get_time_int("17:30"))r=min(end_time,get_time_int("18:00"))ifr>l:res[0]+=r-l total_time-=res[0]iftotal_time==0:returnres# 第二档res[1]=min(total_time,10*60)total_time-=res[1]# 第三档res[2]=total_timereturnres input_line=sys.stdin.readline().strip()res=cal_billing(input_line)print(",".join(map(str,res)))JavaScript
constreadline=require('readline');constrl=readline.createInterface({input:process.stdin,output:process.stdout});// 时间转分钟functiongetTimeInt(time){let[h,m]=time.split(":").map(Number);returnh*60+m;}functioncalBilling(startEnd){letres=[0,0,0];let[start,end]=startEnd.split(" ");letstartTime=getTimeInt(start);letendTime=getTimeInt(end);if(startTime===endTime)returnres;lettotalTime=endTime-startTime;// 第一档 12:00 - 13:30letl=Math.max(startTime,getTimeInt("12:00"));letr=Math.min(endTime,getTimeInt("13:30"));if(r>l)res[0]+=(r-l);// 第一档 17:30 - 18:00l=Math.max(startTime,getTimeInt("17:30"));r=Math.min(endTime,getTimeInt("18:00"));if(r>l)res[0]+=(r-l);totalTime-=res[0];if(totalTime===0)returnres;// 第二档(最多10小时)res[1]=Math.min(totalTime,10*60);totalTime-=res[1];// 第三档res[2]=totalTime;returnres;}rl.on('line',(input)=>{input=input.trim();letres=calBilling(input);console.log(res.join(","));rl.close();});Go
packagemainimport("bufio""fmt""os""strconv""strings")// 时间转分钟funcgetTimeInt(timestring)int{parts:=strings.Split(time,":")h,_:=strconv.Atoi(parts[0])m,_:=strconv.Atoi(parts[1])returnh*60+m}funccalBilling(startEndstring)[3]int{varres[3]inttimeSplit:=strings.Split(startEnd," ")start:=timeSplit[0]end:=timeSplit[1]startTime:=getTimeInt(start)endTime:=getTimeInt(end)ifstartTime==endTime{returnres}totalTime:=endTime-startTime// 第一档l:=max(startTime,getTimeInt("12:00"))r:=min(endTime,getTimeInt("13:30"))ifr>l{res[0]+=r-l}l=max(startTime,getTimeInt("17:30"))r=min(endTime,getTimeInt("18:00"))ifr>l{res[0]+=r-l}totalTime-=res[0]iftotalTime==0{returnres}// 第二档res[1]=min(totalTime,10*60)totalTime-=res[1]// 第三档res[2]=totalTimereturnres}funcmin(a,bint)int{ifa<b{returna}returnb}funcmax(a,bint)int{ifa>b{returna}returnb}funcmain(){reader:=bufio.NewReader(os.Stdin)input,_:=reader.ReadString('\n')input=strings.TrimSpace(input)res:=calBilling(input)fmt.Printf("%d,%d,%d",res[0],res[1],res[2])}C语言
#include<stdio.h>#include<string.h>// 时间转分钟intgetTimeInt(chartime[]){inth,m;sscanf(time,"%d:%d",&h,&m);returnh*60+m;}voidcalBilling(charstartEnd[],intres[3]){charstart[20],end[20];sscanf(startEnd,"%s %s",start,end);intstartTime=getTimeInt(start);intendTime=getTimeInt(end);if(startTime==endTime)return;inttotalTime=endTime-startTime;// 第一档 12:00-13:30intl=startTime>getTimeInt("12:00")?startTime:getTimeInt("12:00");intr=endTime<getTimeInt("13:30")?endTime:getTimeInt("13:30");if(r>l)res[0]+=r-l;// 第一档 17:30-18:00l=startTime>getTimeInt("17:30")?startTime:getTimeInt("17:30");r=endTime<getTimeInt("18:00")?endTime:getTimeInt("18:00");if(r>l)res[0]+=r-l;totalTime-=res[0];if(totalTime==0)return;// 第二档res[1]=totalTime<600?totalTime:600;totalTime-=res[1];// 第三档res[2]=totalTime;}intmain(){charinput[100];fgets(input,sizeof(input),stdin);intres[3]={0};calBilling(input,res);printf("%d,%d,%d",res[0],res[1],res[2]);return0;}