华为OD机试 2025A卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
考勤记录是分析和考核职工工作时间利用情况的原始依据,也是计算职工工资的原始依据。
为了正确地计算职工工资和监督工资基金使用情况,公司决定对员工的收集打卡记录进行异常排查。
如果出现以下两种情况,则认为打卡异常:
- 实际设备号与注册设备号不一样;
- 同一个员工的两个打卡记录的时间小于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、说明
- 根据规则,先比较实际设备号和注册设备号,如果不同,则是异常打卡记录;
- 比较相同工号的打卡记录,如果两个打卡记录的时间小于60分钟 且 打卡距离超过5km,则这两次都是异常打卡;
第二条打卡和第三条打卡,打卡时间小于60 且 打卡距离大于5,所以都是异常打卡。
第六条实际设备号和注册设备号不同,为异常打卡。
因此按顺序输出第二条打卡、第三条打卡、第六条打卡。
五、解题思路
- 读取输入的打卡记录数num;
- 创建一个空的异常打卡记录列表errorList用于存储异常打卡记录;
- 创建一个映射表map,key为工号,value为该工号的打卡记录集合;
- 循环num次,读取每一条打卡记录:
- 解析打卡记录的工号、打卡时间、打卡距离、实际设备号和注册设备号;
- 如果实际设备号与注册设备号不一样,将该记录视为异常打卡,将其添加到异常打卡记录列表errorList中;
- 检查是否有同一个员工的重复打卡记录:
- 如果有同一个员工的重复打卡记录,计算前后两次打卡的时间差和距离差,如果时间差小于60分钟且距离差超过5km,则将这两次打卡记录都视为异常打卡,将它们添加到异常打卡记录列表errorList中;
- 将当前打卡记录添加到对应工号的打卡记录集合中;
- 如果异常打卡记录列表errorList为空,表示没有异常打卡记录,输出"null";
- 将异常打卡记录列表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算法的适用场景,发现新题目,随时更新。