华为OD机试 - 异常的打卡记录(Python/JS/C/C++ 2025 A卷 100分)

在这里插入图片描述

华为OD机试 2025A卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

一、题目描述

考勤记录是分析和考核职工工作时间利用情况的原始依据,也是计算职工工资的原始依据。

为了正确地计算职工工资和监督工资基金使用情况,公司决定对员工的收集打卡记录进行异常排查。

如果出现以下两种情况,则认为打卡异常:

  1. 实际设备号与注册设备号不一样;
  2. 同一个员工的两个打卡记录的时间小于60分钟并且打卡距离超过5km。

给定打卡记录的字符串数组clockRecord(每个打卡记录组成为:工号,时间(分钟),打卡距离(km),实际设备号,注册设备号),返回其中异常的打卡记录(按输入顺序输出)。

二、输入描述

第一行输入为N,表示打卡记录数;

之后的N行为打卡记录,每一行为一条打卡记录。

三、输出描述

按顺序输出异常的打卡记录,分号隔开。

四、测试用例

1、输入

6
1,10,1,100,100
1,80,10,100,100
1,120,16,100,100
2,80,10,200,200
2,150,15,200,200
3,150,15,200,300

2、输出

1,80,10,100,100;1,120,16,100,100;3,150,15,200,300

3、说明

  1. 根据规则,先比较实际设备号和注册设备号,如果不同,则是异常打卡记录;
  2. 比较相同工号的打卡记录,如果两个打卡记录的时间小于60分钟 且 打卡距离超过5km,则这两次都是异常打卡;

第二条打卡和第三条打卡,打卡时间小于60 且 打卡距离大于5,所以都是异常打卡。

第六条实际设备号和注册设备号不同,为异常打卡。

因此按顺序输出第二条打卡、第三条打卡、第六条打卡。

五、解题思路

  1. 读取输入的打卡记录数num;
  2. 创建一个空的异常打卡记录列表errorList用于存储异常打卡记录;
  3. 创建一个映射表map,key为工号,value为该工号的打卡记录集合;
  4. 循环num次,读取每一条打卡记录:
    • 解析打卡记录的工号、打卡时间、打卡距离、实际设备号和注册设备号;
    • 如果实际设备号与注册设备号不一样,将该记录视为异常打卡,将其添加到异常打卡记录列表errorList中;
    • 检查是否有同一个员工的重复打卡记录:
    • 如果有同一个员工的重复打卡记录,计算前后两次打卡的时间差和距离差,如果时间差小于60分钟且距离差超过5km,则将这两次打卡记录都视为异常打卡,将它们添加到异常打卡记录列表errorList中;
    • 将当前打卡记录添加到对应工号的打卡记录集合中;
  5. 如果异常打卡记录列表errorList为空,表示没有异常打卡记录,输出"null";
  6. 将异常打卡记录列表errorList按照输入顺序输出,以分号分隔每条记录;

六、Python算法源码

# 导入必要的库
def check_attendance(records):
    # 打卡异常记录
    error_list = []
    # 打卡记录映射:工号 -> 打卡记录
    record_map = {}

    for line in records:
        arr = line.split(',')
        id = int(arr[0])
        clock_time = int(arr[1])
        clock_distance = int(arr[2])

        # 1. 检查设备号是否一致
        if arr[3] != arr[4]:
            if line not in error_list:
                error_list.append(line)

        # 2. 检查同一员工的两次打卡记录
        if id in record_map:
            for pre_line in record_map[id]:
                pre_arr = pre_line.split(',')
                time_diff = abs(int(pre_arr[1]) - clock_time)
                distance_diff = abs(int(pre_arr[2]) - clock_distance)

                if time_diff < 60 and distance_diff > 5:
                    if pre_line not in error_list:
                        error_list.append(pre_line)
                    if line not in error_list:
                        error_list.append(line)

        # 将当前记录加入打卡记录
        if id not in record_map:
            record_map[id] = []
        record_map[id].append(line)

    return error_list if error_list else ['null']

七、JavaScript算法源码

// 检查打卡记录函数
function checkAttendance(records) {
    let errorList = [];
    let recordMap = {};

    records.forEach(line => {
        const arr = line.split(',');
        const id = parseInt(arr[0]);
        const clockTime = parseInt(arr[1]);
        const clockDistance = parseInt(arr[2]);

        // 1. 检查设备号是否一致
        if (arr[3] !== arr[4]) {
            if (!errorList.includes(line)) {
                errorList.push(line);
            }
        }

        // 2. 检查同一员工的两次打卡记录
        if (recordMap[id]) {
            recordMap[id].forEach(preLine => {
                const split = preLine.split(',');
                const timeDiff = Math.abs(parseInt(split[1]) - clockTime);
                const distanceDiff = Math.abs(parseInt(split[2]) - clockDistance);

                if (timeDiff < 60 && distanceDiff > 5) {
                    if (!errorList.includes(preLine)) {
                        errorList.push(preLine);
                    }
                    if (!errorList.includes(line)) {
                        errorList.push(line);
                    }
                }
            });
        }

        // 记录当前打卡记录
        if (!recordMap[id]) {
            recordMap[id] = [];
        }
        recordMap[id].push(line);
    });

    return errorList.length === 0 ? ['null'] : errorList;
}

八、C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_RECORDS 100
#define MAX_LENGTH 200

// 函数定义
void check_attendance(char records[MAX_RECORDS][MAX_LENGTH], int n) {
    // 打卡异常记录数组
    char errorList[MAX_RECORDS][MAX_LENGTH];
    int errorCount = 0;

    // 工号对应的打卡记录
    char recordMap[MAX_RECORDS][MAX_LENGTH];

    // 处理每条记录
    for (int i = 0; i < n; i++) {
        char line[MAX_LENGTH];
        strcpy(line, records[i]);

        // 分割记录
        char *id_str = strtok(line, ",");
        char *time_str = strtok(NULL, ",");
        char *distance_str = strtok(NULL, ",");
        char *actual_device = strtok(NULL, ",");
        char *registered_device = strtok(NULL, ",");

        int id = atoi(id_str);
        int clockTime = atoi(time_str);
        int clockDistance = atoi(distance_str);

        // 1. 检查设备号是否一致
        if (strcmp(actual_device, registered_device) != 0) {
            strcpy(errorList[errorCount++], records[i]);
        }

        // 2. 检查同一员工的两次打卡记录
        for (int j = 0; j < i; j++) {
            char preLine[MAX_LENGTH];
            strcpy(preLine, records[j]);
            char *preId_str = strtok(preLine, ",");
            char *preTime_str = strtok(NULL, ",");
            char *preDistance_str = strtok(NULL, ",");
            int preTime = atoi(preTime_str);
            int preDistance = atoi(preDistance_str);

            if (abs(clockTime - preTime) < 60 && abs(clockDistance - preDistance) > 5) {
                strcpy(errorList[errorCount++], records[j]);
                strcpy(errorList[errorCount++], records[i]);
            }
        }
    }

    // 输出结果
    if (errorCount == 0) {
        printf("null\n");
    } else {
        for (int i = 0; i < errorCount; i++) {
            printf("%s;", errorList[i]);
        }
        printf("\n");
    }
}

九、C++算法源码

#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <cmath>
#include <sstream>

using namespace std;

void check_attendance(vector<string>& records) {
    vector<string> errorList;
    vector<vector<string>> recordMap(100);

    for (const auto& line : records) {
        stringstream ss(line);
        string id_str, time_str, distance_str, actual_device, registered_device;
        getline(ss, id_str, ',');
        getline(ss, time_str, ',');
        getline(ss, distance_str, ',');
        getline(ss, actual_device, ',');
        getline(ss, registered_device, ',');

        int id = stoi(id_str);
        int clockTime = stoi(time_str);
        int clockDistance = stoi(distance_str);

        // 1. 检查设备号是否一致
        if (actual_device != registered_device) {
            errorList.push_back(line);
        }

        // 2. 检查同一员工的两次打卡记录
        for (const auto& preLine : recordMap[id]) {
            stringstream preSS(preLine);
            string preTime_str, preDistance_str;
            getline(preSS, preTime_str, ',');
            getline(preSS, preDistance_str, ',');

            int preTime = stoi(preTime_str);
            int preDistance = stoi(preDistance_str);

            if (abs(clockTime - preTime) < 60 && abs(clockDistance - preDistance) > 5) {
                if (find(errorList.begin(), errorList.end(), preLine) == errorList.end()) {
                    errorList.push_back(preLine);
                }
                errorList.push_back(line);
            }
        }

        recordMap[id].push_back(line);
    }

    if (errorList.empty()) {
        cout << "null" << endl;
    } else {
        for (const auto& error : errorList) {
            cout << error << ";";
        }
        cout << endl;
    }
}

🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 A卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值