3 solutions

  • 0
    @ 8 months ago
    #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
      @ 8 months ago
      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
        @ 9 months ago

        题目描述

        某高科技公司为员工提供智慧打卡系统,记录员工每日的进出门禁时间。为计算员工的实际工作时长,考虑以下规则:离岗时间不超过 15 分钟的,不扣除工作时长;午休时间为 12:00 至 14:00,此时间段内不算工作时长;晚饭时间为 18:00 至 19:30,此时间段内也不算工作时长。

        输入包括四行:第一行是员工当天进门禁的次数 ( n );第二行是员工当天所有的入门禁时间,以空格分隔(格式为 HH:MM);第三行是员工当天出门禁的次数 ( m );第四行是员工当天所有的出门禁时间,以空格分隔(格式为 HH:MM)。输出为员工当天的工作时长(单位:分钟)。

        思路: 模拟

        若离岗时间不超过15min,那么直接可以将出门禁时间改为下次入门禁时间。对于午休时间和晚饭时间,可以将入门禁时间改为午休和晚饭的结束,出门禁时间改为午休和晚饭的开始。处理后可能会存在单次打卡出门禁时间在入门禁时间之前,直接将本次工作时间置零即可。然后计算单次工作时间。

        题解

        我们需要计算员工的工作时长,具体考虑以下几点:

        1. 输入与数据结构

          • 我们首先读取员工当天的入门禁和出门禁时间。为了方便计算,使用一个 pair<int, int> 的结构来存储时间(小时和分钟)。
        2. 离岗时间的处理

          • 如果员工的离岗时间不超过 15 分钟,可以认为该段时间内不算离岗,因此可以将该次出门禁时间替换为下次入门禁时间。
        3. 午休和晚饭时间的处理

          • 午休时间为 12:00 到 14:00,晚饭时间为 18:00 到 19:30。在计算工作时长时,如果入门禁时间落在午休时间或晚饭时间内,需要调整入门禁和出门禁的时间:
            • 入门禁时间调整为午休结束或晚饭结束的时间。
            • 出门禁时间调整为午休开始或晚饭开始的时间。
        4. 计算有效工作时长

          • 对于每一对入门禁和出门禁时间,计算其对应的工作时长,并累加。如果出门禁时间在入门禁时间之前,则该段工作时间为 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