输出:
100000,80,10,ABCE,ABCD
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

python解法

使用 emp 字典来存储每个员工的最后一次打卡信息。键为员工 ID (eid),值为三元组 (最后一次打卡时间, 最后一次打卡地点, 当前记录的索引)。
使用 result 集合来存储异常记录的索引。
遍历记录:

对于每条记录,首先判断报告地址 (ad) 是否与打卡地址 (rd) 一致,如果不一致,则这条记录是异常的,加入到 result 集合中。
然后,检查该员工的前一次打卡记录,若满足打卡时间差小于 60 分钟且打卡地点相差超过 5 米的条件,则认为这两次打卡是异常的,当前记录与之前的记录都应该加入异常记录集合中。
输出结果:

若存在异常记录,则返回按要求格式化的结果,返回所有异常记录的信息,按照异常记录的索引升序排列。
如果没有异常记录,返回 “null”。

# 输入读取
n = int(input())  # 输入记录数量
cr = [input().split(",") for _ in range(n)]  # 读取n条记录,存储为列表,每条记录是一个列表

def find_abnormal(cr):
    emp = {}  # 用来存储每个员工的最后一次打卡信息
    result = set()  # 用来存储异常记录的索引

    # 遍历所有的打卡记录
    for i in range(len(cr)):
        # 从当前记录中提取员工ID、时间、地点等信息
        eid, t, d, ad, rd = cr[i]
        
        # 1. 判断报告地址与打卡地址是否不一致
        if ad != rd:
            result.add(i)  # 若不一致,加入异常记录集
        
        # 2. 检查是否存在两次打卡时间小于60分钟且地点相差超过5米的情况
        if eid in emp:
            last_t, last_d, idx = emp[eid]  # 获取该员工上次的打卡记录
            
            # 判断时间差小于60分钟且地点差异大于5米
            if int(t) - last_t < 60 and abs(int(d) - last_d) > 5:
                result.add(i)  # 当前记录异常
                result.add(idx)  # 上次记录异常
        
        # 更新该员工的打卡信息
        emp[eid] = (int(t), int(d), i)  # 存储最新的时间、地点和当前记录的索引

    # 如果有异常记录,按照记录索引升序排列并输出
    if result:
        return ";".join(",".join(cr[i]) for i in sorted(result))  # 格式化输出异常记录
    return "null"  # 若无异常记录,返回 "null"

# 输出结果
print(find_abnormal(cr))

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

java解法

打卡地址与报告地址不一致,这条记录是异常的。
打卡时间差小于 60 分钟且地点差异超过 5 米,这两条记录是异常的。
解题步骤:
数据存储:

empData:一个哈希表,用于存储每个员工的打卡记录。键是员工 ID(eid),值是该员工所有的打卡记录列表。
errorIdx:一个集合,用于存储异常记录的索引。
解析记录:

对于每条记录,首先检查报告地址与打卡地址是否一致。如果不一致,将该记录的索引加入异常记录集合 errorIdx。
然后,遍历每个员工的记录,检查相邻的打卡记录,如果时间差小于 60 分钟且地点差异超过 5 米,则认为这两次打卡是异常的,添加到异常记录集合。
排序和输出:

对每个员工的记录按照时间进行排序,然后进行时间差和地点差的检查。
如果有异常记录,按要求格式化输出异常记录;如果没有,输出 “null”。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();  // 读取打卡记录的数量
        String[][] logs = new String[n][];  // 用于存储所有打卡记录

        // 读取所有打卡记录
        for (int i = 0; i < n; i++) {
            logs[i] = input.next().split(",");  // 每条记录按逗号分割
        }

        System.out.println(findAnomalies(logs));  // 调用方法找出异常记录并输出
    }

    // 查找异常打卡记录
    public static String findAnomalies(String[][] logs) {
        HashMap<String, List<String[]>> empData = new HashMap<>();  // 存储每个员工的打卡记录
        Set<Integer> errorIdx = new TreeSet<>();  // 存储异常记录的索引

        // 处理所有记录
        for (int i = 0; i < logs.length; i++) {
            String[] log = Arrays.copyOf(logs[i], logs[i].length + 1);  // 复制记录并扩展,添加记录的索引
            log[log.length - 1] = String.valueOf(i);  // 添加当前记录的索引

            // 1. 如果报告地址与打卡地址不一致,加入异常记录
            if (!log[3].equals(log[4])) {
                errorIdx.add(i);  // 将当前记录索引加入异常记录集合
            }

            // 2. 将打卡记录按照员工 ID 存入 empData
            empData.computeIfAbsent(log[0], k -> new ArrayList<>()).add(log);  // 按员工 ID 存储记录
        }

        // 遍历每个员工的打卡记录,查找符合异常条件的记录
        for (String key : empData.keySet()) {
            List<String[]> records = empData.get(key);  // 获取当前员工的打卡记录
            records.sort(Comparator.comparingInt(a -> Integer.parseInt(a[1])));  // 按照时间排序

            // 检查每两条记录之间的时间差和地点差
            for (int i = 0; i < records.size(); i++) {
                int t1 = Integer.parseInt(records.get(i)[1]);  // 第一条记录的时间
                int d1 = Integer.parseInt(records.get(i)[2]);  // 第一条记录的地点

                // 与之后的记录进行比较
                for (int j = i + 1; j < records.size(); j++) {
                    int t2 = Integer.parseInt(records.get(j)[1]);  // 第二条记录的时间
                    int d2 = Integer.parseInt(records.get(j)[2]);  // 第二条记录的地点

                    // 如果时间差大于等于60分钟,则跳出循环
                    if (t2 - t1 >= 60) break;

                    // 如果时间差小于60分钟,且地点差超过5米,认为两条记录异常
                    if (Math.abs(d2 - d1) > 5) {
                        errorIdx.add(Integer.parseInt(records.get(i)[5]));  // 添加第一条记录的索引
                        errorIdx.add(Integer.parseInt(records.get(j)[5]));  // 添加第二条记录的索引
                    }
                }
            }
        }

        // 如果没有异常记录,返回 "null"
        if (errorIdx.isEmpty()) return "null";

        // 格式化输出异常记录
        StringJoiner sj = new StringJoiner(";");
        for (int idx : errorIdx) {
            sj.add(String.join(",", logs[idx]));  // 将异常记录按照要求的格式连接起来
        }
        return sj.toString();  // 返回格式化后的异常记录
    }
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C++解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

JS解法

报告地址和打卡地址不一致。
同一员工的打卡记录之间,时间差小于 60 分钟,且地点差异大于 5 米。
步骤:
输入数据处理:

记录的格式为 [员工ID, 打卡时间, 打卡地点, 预计打卡地点, 报告打卡地点]。
需要遍历每一条记录,并检查打卡地址是否与报告地址一致。
需要将每一条记录按照员工 ID 分类存储,以便后续对同一员工的打卡记录进行时间和地点差的检查。
判断异常条件:

如果报告地址与打卡地址不一致,记录为异常。
对于每个员工的记录,按照打卡时间升序排序,然后检查相邻记录的时间差和地点差。
如果时间差小于 60 分钟且地点差大于 5 米,则这两条记录都标记为异常。
输出:

如果有异常记录,输出异常记录的内容,按要求格式化(记录间用 ; 分隔)。
如果没有异常记录,输出 “null”。

// 找出所有异常的打卡记录
function findAnomalies(logs) {
    // 用 Map 存储员工的所有打卡记录,键是员工ID,值是该员工的所有打卡记录
    const empData = new Map();
    // 用 Set 存储异常记录的索引
    const errorIdx = new Set();

    // 遍历每条记录
    logs.forEach((log, i) => {
        // 复制记录并添加记录的索引,以便后续引用
        const extendedLog = [...log, i.toString()];

        // 1. 如果报告地址与打卡地址不一致,标记异常
        if (extendedLog[3].trim() !== extendedLog[4].trim()) {
            errorIdx.add(i); // 将异常记录的索引添加到 errorIdx
        }

        // 2. 按员工ID将记录分类存储
        if (!empData.has(extendedLog[0])) {
            empData.set(extendedLog[0], []); // 如果没有该员工,初始化为一个空数组
        }
        empData.get(extendedLog[0]).push(extendedLog); // 将记录加入该员工的记录列表
    });

    // 对每个员工的记录进行处理
    for (const key of empData.keys()) {
        const records = empData.get(key);  // 获取该员工的所有打卡记录
        // 按打卡时间升序排序
        records.sort((a, b) => parseInt(a[1]) - parseInt(b[1]));

        // 遍历员工的打卡记录,检查时间和地点差
        for (let i = 0; i < records.length; i++) {
            const t1 = parseInt(records[i][1]); // 获取第一个记录的时间
            const d1 = parseInt(records[i][2]); // 获取第一个记录的地点

            // 与之后的记录进行比较
            for (let j = i + 1; j < records.length; j++) {
                const t2 = parseInt(records[j][1]); // 获取第二个记录的时间
                const d2 = parseInt(records[j][2]); // 获取第二个记录的地点

                // 如果时间差大于等于60分钟,则跳出循环
                if (t2 - t1 >= 60) break;

                // 如果时间差小于60分钟,且地点差超过5米,认为两条记录异常
                if (Math.abs(d2 - d1) > 5) {
                    // 标记两条记录为异常
                    errorIdx.add(parseInt(records[i][5]));
                    errorIdx.add(parseInt(records[j][5]));
                }
            }
        }
    }

    // 如果没有异常记录,返回 "null"
    if (errorIdx.size === 0) return "null";

    // 格式化输出异常记录
    const result = Array.from(errorIdx)
        .map(idx => logs[idx].join(",")) // 将每条异常记录转换为字符串
        .join(";");  // 用分号连接所有异常记录
    return result;  // 返回格式化后的异常记录
}

// 读取输入数据并调用 findAnomalies 方法
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// 询问输入的记录数量 n
rl.question('', (n) => {
    const logs = [];
    let count = 0;

    // 监听每一行输入
    rl.on('line', (input) => {
        if (input.trim() === '') return;  // 如果输入为空则跳过
        logs.push(input.split(","));  // 将输入的记录按逗号分割,保存到 logs 数组
        count++;
        if (count === parseInt(n)) {  // 如果输入的记录数量达到 n
            console.log(findAnomalies(logs));  // 调用 findAnomalies 输出结果
            rl.close();  // 关闭输入流
        }
    });
});

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/144773262"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!