2024华为OD试题及答案-A048-异常的打卡记录

题目描述

考勤记录是分析和考核职工工作时间利用情况的原始依据,也是计算职工工资的原始依据,为了正确地计算职工工资和监督工资基金使用情况,公司决定对员工的手机打卡记录进行异常排查。


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

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

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

输入描述

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

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

输出描述

输出异常的打卡记录。

备注
  • clockRecords长度 ≤ 1000
  • clockRecords[i] 格式:{id},{time},{distance},{actualDeviceNumber},{registeredDeviceNumber}
  • id由6位数字组成
  • time由整数组成,范围为0~1000
  • distance由整数组成,范围为0~100
  • actualDeviceNumber与registeredDeviceNumber由思维大写字母组成

用例
输入2
100000,10,1,ABCD,ABCD
100000,50,10,ABCD,ABCD
输出100000,10,1,ABCD,ABCD;100000,50,10,ABCD,ABCD
说明第一条记录是异常得,因为第二题记录与它得间隔不超过60分钟,但是打卡距离超过了5km,同理第二条记录也是异常得。
输入2
100000,10,1,ABCD,ABCD
100001,80,10,ABCE,ABCE
输出null
说明无异常打卡记录,所以返回null
输入2
100000,10,1,ABCD,ABCD
100000,80,10,ABCE,ABCD
输出100000,80,10,ABCE,ABCD
说明第二条记录得注册设备号与打卡设备号不一致,所以是异常记录

解题思路

我们需要分析打卡记录,并根据以下两个条件判断打卡记录是否异常:

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

具体步骤如下:

  1. 读取输入的打卡记录数量 NNN 以及每条打卡记录。
  2. 对每条打卡记录进行检查:
    • 检查实际设备号与注册设备号是否一致。
    • 检查同一员工的两个打卡记录之间的时间差和距离差。
  3. 收集所有异常的打卡记录,并按输入顺序输出。

C++程序

 
#include <iostream>
#include <vector>
#include <sstream>
#include <unordered_map>
#include <cmath>

using namespace std;

struct Record {
    string id;
    int time;
    int distance;
    string actualDevice;
    string registeredDevice;
};

bool isAbnormal(const Record& r1, const Record& r2) {
    return (abs(r1.time - r2.time) < 60 && abs(r1.distance - r2.distance) > 5);
}

int main() {
    int N;
    cin >> N;
    cin.ignore();

    vector<Record> records(N);
    unordered_map<string, vector<Record>> employeeRecords;

    for (int i = 0; i < N; ++i) {
        string line;
        getline(cin, line);
        stringstream ss(line);
        Record r;
        getline(ss, r.id, ',');
        ss >> r.time;
        ss.ignore(1);
        ss >> r.distance;
        ss.ignore(1);
        getline(ss, r.actualDevice, ',');
        getline(ss, r.registeredDevice);
        records[i] = r;
        employeeRecords[r.id].push_back(r);
    }

    vector<string> abnormalRecords;

    for (int i = 0; i < N; ++i) {
        const Record& r = records[i];
        if (r.actualDevice != r.registeredDevice) {
            abnormalRecords.push_back(to_string(i + 1));
            continue;
        }
        for (const Record& prev : employeeRecords[r.id]) {
            if (prev.time < r.time && isAbnormal(prev, r)) {
                abnormalRecords.push_back(to_string(i + 1));
                break;
            }
        }
    }

    for (const string& index : abnormalRecords) {
        cout << index << endl;
    }

    return 0;
}

Python程序

 
def parse_record(line):
    parts = line.split(',')
    return {
        'id': parts[0],
        'time': int(parts[1]),
        'distance': int(parts[2]),
        'actualDevice': parts[3],
        'registeredDevice': parts[4]
    }

def is_abnormal(record1, record2):
    return abs(record1['time'] - record2['time']) < 60 and abs(record1['distance'] - record2['distance']) > 5

def find_abnormal_records(records):
    employee_records = {}
    abnormal_indices = []

    for i, record in enumerate(records):
        if record['actualDevice'] != record['registeredDevice']:
            abnormal_indices.append(i + 1)
            continue

        if record['id'] not in employee_records:
            employee_records[record['id']] = []

        for prev_record in employee_records[record['id']]:
            if prev_record['time'] < record['time'] and is_abnormal(prev_record, record):
                abnormal_indices.append(i + 1)
                break

        employee_records[record['id']].append(record)

    return abnormal_indices

# 读取输入
N = int(input())
records = [parse_record(input().strip()) for _ in range(N)]

# 找到异常打卡记录
abnormal_indices = find_abnormal_records(records)

# 输出异常打卡记录
for index in abnormal_indices:
    print(index)

用例验证

输入
 
5
000001,540,10,DEVICE1,DEVICE1
000001,600,18,DEVICE1,DEVICE2
000002,480,15,DEVICE1,DEVICE1
000002,530,23,DEVICE1,DEVICE1
000003,500,12,DEVICE2,DEVICE2

输出
 
2
4

解释:第二条记录的设备号不匹配,第四条记录的时间差小于60分钟且距离差大于5公里。

以上代码可以通过给定的用例验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值