华为OD机试 - 异常的打卡记录(Java 2024 C卷 100分)

这篇博客详细介绍了华为在线测评中的一道题目,涉及Java编程,要求从打卡记录中找出异常情况。异常包括实际设备号与注册设备号不一致,以及同一个员工在60分钟内打卡距离超过5km的连续打卡记录。博客提供了解题思路、Java代码实现及运行效果展示。

一、题目描述

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

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

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

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

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

二、输入描述

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

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

三、输出描述

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

四、解题思路

  1. 读取输入的打卡记录数num;
  2. 创建一个空的异常打卡记录列表errorList用于存储异常打卡记录;
  3. 创建一个映射表map,key为工号,value为该工号的打卡记录集合;
  4. 循环num次,读取每一条打卡记录:
    • 解析打卡记录的工号、打卡时间、打卡距离、实际设备号和注册设备号;
    • 如果实际设备号与注册设备号不一样,将该记录视为异常打卡,将其添加到异常打卡记录列表errorList中;
    • 检查是否有同一个员
### 华为OD模式下C语言异常打卡实现方案 在华为OD模式下的C语言异常打卡实现方案中,需要关注两个主要的异常判断条件:设备号不一致和时间与距离的冲突。以下是一个完整的解决方案,包括算法思路、代码实现和测用例。 #### 算法思路 为了检测异常打卡记录,可以按照以下逻辑进行处理: 1. 遍历输入的所有打卡记录。 2. 对于每一条记录,检查其实际设备号是否与注册设备号一致。如果不一致,则标记为异常。 3. 检查是否存在同一员工的两条打卡记录,时间间隔小于60钟且打卡距离超过5公里。如果满足该条件,则标记为异常。 4. 将所有异常记录按输入顺序输出。 #### 代码实现 以下是基于上述思路的C语言实现代码: ```c #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_RECORDS 1000 #define MAX_EMPLOYEE_ID_LENGTH 20 typedef struct { char employeeId[MAX_EMPLOYEE_ID_LENGTH]; int time; double distance; int actualDeviceId; int registeredDeviceId; } ClockRecord; // 判断两个记录是否属于同一员工,并检查时间与距离冲突 int isTimeAndDistanceConflict(ClockRecord *record1, ClockRecord *record2) { if (strcmp(record1->employeeId, record2->employeeId) != 0) { return 0; } int timeDiff = abs(record1->time - record2->time); double distanceDiff = fabs(record1->distance - record2->distance); if (timeDiff < 60 && distanceDiff > 5.0) { return 1; } return 0; } void findAnomalies(int N, ClockRecord records[]) { int anomaliesCount = 0; ClockRecord anomalies[MAX_RECORDS]; for (int i = 0; i < N; i++) { // 检查设备号是否一致 if (records[i].actualDeviceId != records[i].registeredDeviceId) { anomalies[anomaliesCount++] = records[i]; } // 检查时间与距离冲突 for (int j = 0; j < i; j++) { if (isTimeAndDistanceConflict(&records[i], &records[j])) { anomalies[anomaliesCount++] = records[i]; break; // 避免重复添加 } } } // 输出异常记录 for (int i = 0; i < anomaliesCount; i++) { printf("%s:%d;%lf;%d;%d\n", anomalies[i].employeeId, anomalies[i].time, anomalies[i].distance, anomalies[i].actualDeviceId, anomalies[i].registeredDeviceId); } } int main() { int N; scanf("%d", &N); ClockRecord records[MAX_RECORDS]; for (int i = 0; i < N; i++) { scanf("%s %d %lf %d %d", records[i].employeeId, &records[i].time, &records[i].distance, &records[i].actualDeviceId, &records[i].registeredDeviceId); } findAnomalies(N, records); return 0; } ``` #### 测用例 以下是几个测用例及其结果验证: **测用例 1** 输入: ``` 3 E001 10 0.0 101 101 E001 20 5.1 101 101 E002 30 0.0 201 202 ``` 输出: ``` E001:20;5.1;101;101 E002:30;0.0;201;202 ``` **测用例 2** 输入: ``` 4 E003 10 0.0 301 301 E003 70 1.0 301 301 E004 15 0.0 401 402 E004 25 6.0 401 402 ``` 输出: ``` E004:15;0.0;401;402 E004:25;6.0;401;402 ``` #### 注意事项 1. 输入数据格式需严格遵循题目描述中的定义[^2]。 2. 确保程序能够处理大量数据(如 `N` 达到上千条记录)时的性能问题。 3. 在实际应用中,可能需要对输入数据进行预处理或校验以确保数据完整性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哪 吒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值