3 solutions
-
0
#include <cstdio> #include <iostream> #include <string> #include <cmath> #include <utility> #include <vector> using namespace std; int cal(pair<int,int>& a,pair<int,int>b){ if (a>=b) { return 0; } return (b.first-a.first)*60+(b.second-a.second); } int main(){ int n; cin>>n; vector<pair<int,int>> enter,out; int h,m,mm; for (int i=0; i<n; i++) { scanf("%d:%d",&h,&m); enter.emplace_back(h,m); } cin>> mm; for (int i=0; i<mm; i++) { scanf("%d:%d",&h,&m); if (i!=mm-1) { pair<int, int> mypair(h,m); if (cal(mypair,enter[i+1])<=15) { out.push_back(enter[i+1]); continue; } } out.emplace_back(h,m); } for (auto& s:enter) { if (s.first>=12&&s.first<14) { s.first=14; s.second=0; } if (s.first==18||(s.first==19&&s.second<=30)) { s.first=19; s.second=30; } } int res=0; for (int i=0;i<n;i++) { if (out[i].first>=12&&out[i].first<14) { out[i].first=12; out[i].second=0; } if (out[i].first==18||(out[i].first==19&&out[i].second<=30)) { out[i].first=18; out[i].second=0; } res+=cal(enter[i],out[i]); } cout<<res<<endl; }
-
0
def convert(time_text): # 将时间字符串转换为分钟数 h, m = map(int, time_text.split(':')) return h * 60 + m n = int(input()) times = input().split() in_times = [convert(each) for each in times] # 将上班时间转换为分钟数 n = int(input()) times = input().split() out_times = [convert(each) for each in times] # 将下班时间转换为分钟数 # 创建工作信息列表,包含每个人的上班和下班时间 work_info = [[in_times[i], out_times[i]] for i in range(n)] # 合并相邻的工作时间段 for i in range(n - 1): if work_info[i + 1][0] - work_info[i][1] <= 15: work_info[i + 1][0] = work_info[i][1] # 更新下一个人的上班时间为当前人的下班时间 work_time_set = set() # 创建一个集合来存储工作时间段 for each in work_info: work_time_set = work_time_set | set(range(each[0], each[1])) # 使用集合的并集操作 new_work_time_set = work_time_set.copy() # 复制工作时间集合以进行后续处理 # 移除不在工作时间段内的时间 for each in work_time_set: if 720 <= each < 840 or 1080 <= each < 1170: new_work_time_set.remove(each) # 输出有效工作时间段的数量 print(len(new_work_time_set))
-
0
题目描述
某高科技公司为员工提供智慧打卡系统,记录员工每日的进出门禁时间。为计算员工的实际工作时长,考虑以下规则:离岗时间不超过 15 分钟的,不扣除工作时长;午休时间为 12:00 至 14:00,此时间段内不算工作时长;晚饭时间为 18:00 至 19:30,此时间段内也不算工作时长。
输入包括四行:第一行是员工当天进门禁的次数 ( n );第二行是员工当天所有的入门禁时间,以空格分隔(格式为 HH:MM);第三行是员工当天出门禁的次数 ( m );第四行是员工当天所有的出门禁时间,以空格分隔(格式为 HH:MM)。输出为员工当天的工作时长(单位:分钟)。
思路: 模拟
若离岗时间不超过15min,那么直接可以将出门禁时间改为下次入门禁时间。对于午休时间和晚饭时间,可以将入门禁时间改为午休和晚饭的结束,出门禁时间改为午休和晚饭的开始。处理后可能会存在单次打卡出门禁时间在入门禁时间之前,直接将本次工作时间置零即可。然后计算单次工作时间。
题解
我们需要计算员工的工作时长,具体考虑以下几点:
-
输入与数据结构:
- 我们首先读取员工当天的入门禁和出门禁时间。为了方便计算,使用一个
pair<int, int>
的结构来存储时间(小时和分钟)。
- 我们首先读取员工当天的入门禁和出门禁时间。为了方便计算,使用一个
-
离岗时间的处理:
- 如果员工的离岗时间不超过 15 分钟,可以认为该段时间内不算离岗,因此可以将该次出门禁时间替换为下次入门禁时间。
-
午休和晚饭时间的处理:
- 午休时间为 12:00 到 14:00,晚饭时间为 18:00 到 19:30。在计算工作时长时,如果入门禁时间落在午休时间或晚饭时间内,需要调整入门禁和出门禁的时间:
- 入门禁时间调整为午休结束或晚饭结束的时间。
- 出门禁时间调整为午休开始或晚饭开始的时间。
- 午休时间为 12:00 到 14:00,晚饭时间为 18:00 到 19:30。在计算工作时长时,如果入门禁时间落在午休时间或晚饭时间内,需要调整入门禁和出门禁的时间:
-
计算有效工作时长:
- 对于每一对入门禁和出门禁时间,计算其对应的工作时长,并累加。如果出门禁时间在入门禁时间之前,则该段工作时间为 0。
代码
C++
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mr make_pair #define fi first #define se second typedef pair<int, int> Pii; // 计算两次打卡时间的差值(返回有效工作时长) int cal(Pii p1, Pii p2) { if (p2 <= p1) return 0; // 如果出门禁时间在入门禁时间之前,则置零 return (p2.fi - p1.fi - 1) * 60 + (60 - p1.se + p2.se); } int main() { int n, mm, h, m; cin >> n; // 读取入门禁次数 vector<Pii> s, e; // s存储入门禁时间,e存储出门禁时间 // 读取入门禁时间 for (int i = 0; i < n; i++) { scanf("%d:%d", &h, &m); s.pb(mr(h, m)); // 将时间存储为pair } cin >> mm; // 读取出门禁次数 int ans = 0; // 初始化工作时长 for (int i = 0; i < mm; i++) { scanf("%d:%d", &h, &m); if (i != mm - 1) { // 如果当前出门禁时间与下一个入门禁时间的差值小于等于15分钟 if (cal(mr(h, m), s[i + 1]) <= 15) { e.pb(s[i + 1]); // 将出门禁时间替换为下次入门禁时间 continue; } } e.pb(mr(h, m)); // 存储当前出门禁时间 } // 处理午休和晚饭的时间段 for (int i = 0; i < n; i++) { if (s[i].fi < 14 && s[i].fi >= 12) s[i].fi = 14, s[i].se = 0; // 入门禁时间在午休期间,调整为14:00 if (s[i].fi == 18 || (s[i].fi == 19 && s[i].se <= 30)) s[i].fi = 19, s[i].se = 30; // 入门禁时间在晚饭期间,调整为19:30 } for (int i = 0; i < mm; i++) { if (e[i].fi < 14 && e[i].fi >= 12) e[i].fi = 12, e[i].se = 0; // 出门禁时间在午休期间,调整为12:00 if (e[i].fi == 18 || (e[i].fi == 19 && e[i].se <= 30)) e[i].fi = 18, e[i].se = 0; // 出门禁时间在晚饭期间,调整为18:00 // 计算有效工作时长并累加 ans += cal(s[i], e[i]); } cout << ans << endl; // 输出总工作时长 return 0; }
java
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { // 定义一个Pair类,用于存储时间的小时和分钟 static class Pair { int fi, se; // fi代表小时,se代表分钟 Pair(int fi, int se) { this.fi = fi; // 初始化小时 this.se = se; // 初始化分钟 } // 比较当前时间与其他时间,判断是否小于等于 boolean lessThanOrEqualTo(Pair other) { return this.fi < other.fi || (this.fi == other.fi && this.se <= other.se); } } // 计算两次打卡时间的差值(返回有效工作时长) static int cal(Pair p1, Pair p2) { if (p2.lessThanOrEqualTo(p1)) return 0; // 如果出门禁时间在入门禁时间之前,则置零 // 计算工作时长 return (p2.fi - p1.fi - 1) * 60 + (60 - p1.se + p2.se); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 创建扫描器以读取输入 int n = sc.nextInt(); // 读取入门禁次数 List<Pair> s = new ArrayList<>(); // 存储入门禁时间 List<Pair> e = new ArrayList<>(); // 存储出门禁时间 // 读取入门禁时间 for (int i = 0; i < n; i++) { String[] str = sc.next().split(":"); // 按照':'分割时间字符串 int h = Integer.parseInt(str[0]); // 解析小时 int m = Integer.parseInt(str[1]); // 解析分钟 s.add(new Pair(h, m)); // 将时间存储为Pair对象 } int mm = sc.nextInt(); // 读取出门禁次数 int ans = 0; // 初始化工作时长 // 读取出门禁时间 for (int i = 0; i < mm; i++) { String[] str = sc.next().split(":"); // 按照':'分割时间字符串 int h = Integer.parseInt(str[0]); // 解析小时 int m = Integer.parseInt(str[1]); // 解析分钟 // 如果不是最后一次出门禁 if (i != mm - 1) { // 若离岗时间不超过15分钟,则将出门禁时间改为下次入门禁时间 if (cal(new Pair(h, m), s.get(i + 1)) <= 15) { e.add(new Pair(s.get(i + 1).fi, s.get(i + 1).se)); // 使用下一个入门禁时间 continue; // 跳过当前循环 } } e.add(new Pair(h, m)); // 存储当前出门禁时间 } // 处理午休和晚饭的时间段 for (int i = 0; i < n; i++) { if (s.get(i).fi < 14 && s.get(i).fi >= 12) { // 如果入门禁时间在午休期间 s.get(i).fi = 14; // 将入门禁时间调整为14:00 s.get(i).se = 0; // 分钟部分设置为0 } if (s.get(i).fi == 18 || (s.get(i).fi == 19 && s.get(i).se <= 30)) { // 如果入门禁时间在晚饭期间 s.get(i).fi = 19; // 将入门禁时间调整为19:30 s.get(i).se = 30; } } // 处理出门禁时间 for (int i = 0; i < mm; i++) { if (e.get(i).fi < 14 && e.get(i).fi >= 12) { // 如果出门禁时间在午休期间 e.get(i).fi = 12; // 将出门禁时间调整为12:00 e.get(i).se = 0; // 分钟部分设置为0 } if (e.get(i).fi == 18 || (e.get(i).fi == 19 && e.get(i).se <= 30)) { // 如果出门禁时间在晚饭期间 e.get(i).fi = 18; // 将出门禁时间调整为18:00 e.get(i).se = 0; // 分钟部分设置为0 } ans += cal(s.get(i), e.get(i)); // 计算有效工作时长并累加 } System.out.println(ans); // 输出总工作时长 } }
python
def cal(p1, p2): # 计算两次打卡时间的差值(返回有效工作时长) if p2 <= p1: # 处理后可能会存在单次打卡出门禁时间在入门禁时间之前,直接置零 return 0 # 计算工作时长,考虑小时和分钟的差值 return (p2[0] - p1[0] - 1) * 60 + (60 - p1[1] + p2[1]) # 读取入门禁次数 n = int(input()) s = [] # 存储入门禁时间 str = list(input().split()) # 读取入门禁时间字符串并分割 for i in range(n): h, m = map(int, str[i].split(":")) # 将HH:MM格式的时间解析为小时和分钟 s.append((h, m)) # 存储为元组 (小时, 分钟) # 读取出门禁次数 mm = int(input()) e = [] # 存储出门禁时间 str = list(input().split()) # 读取出门禁时间字符串并分割 for i in range(mm): h, m = map(int, str[i].split(":")) # 将HH:MM格式的时间解析为小时和分钟 # 如果不是最后一次出门禁 if i != mm - 1: # 若离岗时间不超过15分钟,则将出门禁时间替换为下次入门禁时间 if cal((h, m), s[i + 1]) <= 15: e.append(s[i + 1]) # 使用下一个入门禁时间 continue # 跳过当前循环 e.append((h, m)) # 存储当前出门禁时间 # 处理午休和晚饭的时间段 for i in range(n): if 12 <= s[i][0] < 14: # 如果入门禁时间在午休期间 s[i] = (14, 0) # 将入门禁时间调整为14:00 if s[i][0] == 18 or (s[i][0] == 19 and s[i][1] <= 30): s[i] = (19, 30) # 将入门禁时间调整为19:30 # 处理出门禁时间 for i in range(mm): if 12 <= e[i][0] < 14: # 如果出门禁时间在午休期间 e[i] = (12, 0) # 将出门禁时间调整为12:00 if e[i][0] == 18 or (e[i][0] == 19 and e[i][1] <= 30): e[i] = (18, 0) # 将出门禁时间调整为18:00 # 计算总的工作时长 ans = 0 for i in range(mm): ans += cal(s[i], e[i]) # 累加每段工作时间 print(ans) # 输出总工作时长
-
- 1
Information
- ID
- 48
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 5
- Tags
- # Submissions
- 357
- Accepted
- 83
- Uploaded By