当前位置: 首页 > article >正文

【2024年华为OD机试】 (C卷,100分)- 考勤信息(JavaScriptJava PythonC/C++)

在这里插入图片描述

一、问题描述

公司用一个字符串来表示员工的出勤信息,具体包括以下几种状态:

  • absent:缺勤
  • late:迟到
  • leaveearly:早退
  • present:正常上班

现需根据员工出勤信息,判断本次是否能获得出勤奖。获得出勤奖的条件如下:

  1. 缺勤不超过一次
  2. 没有连续的迟到/早退
  3. 任意连续7次考勤,缺勤/迟到/早退不超过3次

输入描述

  • 用户的考勤数据字符串。
  • 记录条数 >= 1;
  • 输入字符串长度 < 10000;
  • 不存在非法输入。

示例输入

2
present
present absent present present leaveearly present absent

输出描述

根据考勤数据字符串,如果能得到出勤奖,输出 "true";否则输出 "false"

示例输出

true
false

题目解析

1. 出勤奖条件分析

条件1:缺勤不超过一次
  • 统计整个考勤记录中 absent 的次数。
  • 如果 absent 的次数 > 1,则不满足条件。
条件2:没有连续的迟到/早退
  • 遍历考勤记录,检查是否存在连续的 lateleaveearly
  • 如果存在连续的 lateleaveearly,则不满足条件。
条件3:任意连续7次考勤,缺勤/迟到/早退不超过3次
  • 使用滑动窗口统计任意连续7次考勤中 absentlateleaveearly 的总次数。
  • 如果任意窗口内这些状态的总次数 > 3,则不满足条件。

2. 滑动窗口的应用

滑动窗口是解决此类问题的有效方法。具体步骤如下:

  1. 窗口定义

    • 窗口长度为7。
    • 当窗口右边界索引 R < 7 时,窗口长度为 R + 1
    • 当窗口右边界索引 R >= 7 时,窗口长度为7,左边界索引 L = R - 6
  2. 统计窗口内的状态

    • 统计窗口内 present 的次数。
    • 通过窗口长度减去 present 的次数,得到 absentlateleaveearly 的总次数。
  3. 判断条件

    • 如果窗口内 absentlateleaveearly 的总次数 > 3,则不满足条件。

3. 解题思路

  1. 遍历考勤记录

    • 统计 absent 的总次数,判断是否超过1次。
    • 检查是否存在连续的 lateleaveearly
  2. 滑动窗口统计

    • 使用滑动窗口统计任意连续7次考勤中 absentlateleaveearly 的总次数。
    • 如果任意窗口内这些状态的总次数 > 3,则不满足条件。
  3. 综合判断

    • 如果所有条件均满足,则输出 "true";否则输出 "false"

4. 示例解析

示例1

输入

2
present
present present

输出

true
true

解析

  • 第一个记录:只有 present,满足所有条件。
  • 第二个记录:只有 present,满足所有条件。
示例2

输入

2
present
present absent present present leaveearly present absent

输出

true
false

解析

  • 第一个记录:只有 present,满足所有条件。
  • 第二个记录:
    • absent 出现2次,不满足条件1。
    • 存在 leaveearlyabsent,但未连续,满足条件2。
    • 滑动窗口检查发现某些窗口内 absentlateleaveearly 的总次数 > 3,不满足条件3。

5. 总结

本题的核心在于:

  1. 条件1:统计 absent 的总次数。
  2. 条件2:检查是否存在连续的 lateleaveearly
  3. 条件3:使用滑动窗口统计任意连续7次考勤中 absentlateleaveearly 的总次数。

通过合理设计滑动窗口和遍历逻辑,可以高效解决此类问题。

二、JavaScript算法源码

以下是代码的详细注释和讲解,帮助理解每一部分的逻辑和实现。


代码结构

  1. 主函数
    • 读取输入数据并解析。
    • 调用 getResult 函数处理每条考勤记录。
  2. getResult 函数
    • 遍历每条考勤记录,调用 isAward 函数判断是否能获得出勤奖。
  3. isAward 函数
    • 核心逻辑,判断单条考勤记录是否满足出勤奖的条件。

代码逐行注释

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
  // 读取输入的记录条数
  const n = parseInt(await readline());
  const records = [];

  // 读取每条考勤记录并存入数组
  for (let i = 0; i < n; i++) {
    records.push((await readline()).split(" "));
  }

  // 调用 getResult 函数处理所有记录
  getResult(records);
})();

function getResult(records) {
  // 遍历每条考勤记录,调用 isAward 函数判断是否能获得出勤奖
  for (let record of records) console.log(isAward(record));
}

function isAward(record) {
  // 总缺勤次数
  let absent = 0;

  // 滑窗内正常上班的次数
  let present = 0;

  // 记录前一次的考勤记录
  let preRecord = "";

  // 遍历考勤记录
  for (let i = 0; i < record.length; i++) {
    // 滑窗长度最大为7,如果超过7,则滑窗的左边界需要右移
    // 滑窗失去的部分是 record[i - 7]
    // 如果失去部分是 present,则更新滑窗内 present 次数
    if (i >= 7) {
      if ("present" == record[i - 7]) present--;
    }

    // 当前的考勤记录
    const curRecord = record[i];

    // 根据当前考勤记录的类型进行处理
    switch (curRecord) {
      case "absent":
        // 缺勤不超过一次
        if (++absent > 1) return false;
        break;
      case "late":
      case "leaveearly":
        // 没有连续的迟到/早退
        if ("late" == preRecord || "leaveearly" == preRecord) return false;
        break;
      case "present":
        // 正常上班,滑窗内 present 次数加1
        present++;
        break;
    }

    // 更新前一次的考勤记录
    preRecord = curRecord;

    // 任意连续7次考勤,缺勤/迟到/早退不超过3次
    // 相当于判断:滑窗长度 - present次数 <= 3
    const window_len = Math.min(i + 1, 7);
    if (window_len - present > 3) return false;
  }

  // 如果所有条件都满足,返回 true
  return true;
}

代码逻辑详解

1. 主函数
  • rl:创建一个 readline 接口,用于读取用户输入。
  • iter:获取异步迭代器,用于逐行读取输入。
  • readline 函数:异步读取一行输入。
  • void (async function () { ... })();
    • 立即执行一个异步函数,读取输入数据并解析。
    • 读取记录条数 n
    • 读取每条考勤记录并存入 records 数组。
    • 调用 getResult 函数处理所有记录。

2. getResult 函数
  • 功能:遍历每条考勤记录,调用 isAward 函数判断是否能获得出勤奖。
  • for (let record of records)
    • 遍历 records 数组中的每条考勤记录。
    • 调用 isAward 函数判断当前记录是否满足条件。
    • 输出结果(truefalse)。

3. isAward 函数
  • 功能:判断单条考勤记录是否满足出勤奖的条件。
  • 变量说明
    • absent:统计缺勤次数。
    • present:统计滑窗内正常上班的次数。
    • preRecord:记录前一次的考勤记录,用于判断是否有连续的迟到/早退。
  • 遍历考勤记录
    • 滑窗逻辑
      • 滑窗长度最大为7。
      • 如果当前索引 i >= 7,则滑窗左边界右移,失去的部分是 record[i - 7]
      • 如果失去的部分是 present,则滑窗内 present 次数减1。
    • 当前考勤记录处理
      • absent
        • 缺勤次数加1。
        • 如果缺勤次数 > 1,返回 false
      • lateleaveearly
        • 检查前一次考勤记录是否是 lateleaveearly
        • 如果是,则存在连续的迟到/早退,返回 false
      • present
        • 滑窗内 present 次数加1。
    • 更新前一次考勤记录
      • 将当前考勤记录赋值给 preRecord
    • 滑窗内缺勤/迟到/早退次数检查
      • 计算滑窗长度 window_len(当前索引 + 1,最大为7)。
      • 如果滑窗长度减去 present 次数 > 3,返回 false
  • 返回结果
    • 如果所有条件都满足,返回 true

示例运行

输入:
2
present
present absent present present leaveearly present absent
输出:
true
false
解析:
  1. 第一条记录
    • 只有 present,满足所有条件,输出 true
  2. 第二条记录
    • absent 出现2次,不满足条件1。
    • 存在 leaveearlyabsent,但未连续,满足条件2。
    • 滑动窗口检查发现某些窗口内 absentlateleaveearly 的总次数 > 3,不满足条件3。
    • 输出 false

总结

  • 代码通过遍历考勤记录,结合滑动窗口和状态统计,高效判断是否满足出勤奖的条件。
  • 核心逻辑集中在 isAward 函数中,通过滑窗和状态检查实现条件判断。

三、Java算法源码

以下是 Java 代码的详细注释和讲解,帮助理解每一部分的逻辑和实现。


代码结构

  1. 主函数 main
    • 读取输入数据并解析。
    • 调用 getResult 函数处理每条考勤记录。
  2. getResult 函数
    • 遍历每条考勤记录,调用 isAward 函数判断是否能获得出勤奖。
  3. isAward 函数
    • 核心逻辑,判断单条考勤记录是否满足出勤奖的条件。

代码逐行注释

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    // 读取输入的记录条数
    int n = Integer.parseInt(sc.nextLine());

    // 初始化考勤记录数组
    String[][] records = new String[n][];
    for (int i = 0; i < n; i++) {
      // 读取每条考勤记录并拆分为数组
      records[i] = sc.nextLine().split(" ");
    }

    // 调用 getResult 函数处理所有记录
    getResult(n, records);
  }

  public static void getResult(int n, String[][] records) {
    // 遍历每条考勤记录,调用 isAward 函数判断是否能获得出勤奖
    for (int i = 0; i < n; i++) {
      System.out.println(isAward(records[i]));
    }
  }

  public static boolean isAward(String[] record) {
    // 总缺勤次数
    int absent = 0;

    // 滑窗内正常上班的次数
    int present = 0;

    // 记录前一次的考勤记录
    String preRecord = "";

    // 遍历考勤记录
    for (int i = 0; i < record.length; i++) {
      // 滑窗长度最大为7,如果超过7,则滑窗的左边界需要右移
      // 滑窗失去的部分是 record[i - 7]
      // 如果失去部分是 present,则更新滑窗内 present 次数
      if (i >= 7) {
        if ("present".equals(record[i - 7])) present--;
      }

      // 当前的考勤记录
      String curRecord = record[i];

      // 根据当前考勤记录的类型进行处理
      switch (curRecord) {
        case "absent":
          // 缺勤不超过一次
          if (++absent > 1) return false;
          break;
        case "late":
        case "leaveearly":
          // 没有连续的迟到/早退
          if ("late".equals(preRecord) || "leaveearly".equals(preRecord)) return false;
          break;
        case "present":
          // 正常上班,滑窗内 present 次数加1
          present++;
          break;
      }

      // 更新前一次的考勤记录
      preRecord = curRecord;

      // 任意连续7次考勤,缺勤/迟到/早退不超过3次
      // 相当于判断:滑窗长度 - present次数 <= 3
      int window_len = Math.min(i + 1, 7); // 滑窗长度
      if (window_len - present > 3) return false;
    }

    // 如果所有条件都满足,返回 true
    return true;
  }
}

代码逻辑详解

1. 主函数 main
  • Scanner sc = new Scanner(System.in);
    • 创建一个 Scanner 对象,用于读取用户输入。
  • int n = Integer.parseInt(sc.nextLine());
    • 读取记录条数 n
  • String[][] records = new String[n][];
    • 初始化一个二维数组 records,用于存储每条考勤记录。
  • for (int i = 0; i < n; i++) { ... }
    • 读取每条考勤记录并拆分为数组,存入 records 中。
  • getResult(n, records);
    • 调用 getResult 函数处理所有记录。

2. getResult 函数
  • 功能:遍历每条考勤记录,调用 isAward 函数判断是否能获得出勤奖。
  • for (int i = 0; i < n; i++) { ... }
    • 遍历 records 数组中的每条考勤记录。
    • 调用 isAward 函数判断当前记录是否满足条件。
    • 输出结果(truefalse)。

3. isAward 函数
  • 功能:判断单条考勤记录是否满足出勤奖的条件。
  • 变量说明
    • absent:统计缺勤次数。
    • present:统计滑窗内正常上班的次数。
    • preRecord:记录前一次的考勤记录,用于判断是否有连续的迟到/早退。
  • 遍历考勤记录
    • 滑窗逻辑
      • 滑窗长度最大为7。
      • 如果当前索引 i >= 7,则滑窗左边界右移,失去的部分是 record[i - 7]
      • 如果失去的部分是 present,则滑窗内 present 次数减1。
    • 当前考勤记录处理
      • absent
        • 缺勤次数加1。
        • 如果缺勤次数 > 1,返回 false
      • lateleaveearly
        • 检查前一次考勤记录是否是 lateleaveearly
        • 如果是,则存在连续的迟到/早退,返回 false
      • present
        • 滑窗内 present 次数加1。
    • 更新前一次考勤记录
      • 将当前考勤记录赋值给 preRecord
    • 滑窗内缺勤/迟到/早退次数检查
      • 计算滑窗长度 window_len(当前索引 + 1,最大为7)。
      • 如果滑窗长度减去 present 次数 > 3,返回 false
  • 返回结果
    • 如果所有条件都满足,返回 true

示例运行

输入:
2
present
present absent present present leaveearly present absent
输出:
true
false
解析:
  1. 第一条记录
    • 只有 present,满足所有条件,输出 true
  2. 第二条记录
    • absent 出现2次,不满足条件1。
    • 存在 leaveearlyabsent,但未连续,满足条件2。
    • 滑动窗口检查发现某些窗口内 absentlateleaveearly 的总次数 > 3,不满足条件3。
    • 输出 false

总结

  • 代码通过遍历考勤记录,结合滑动窗口和状态统计,高效判断是否满足出勤奖的条件。
  • 核心逻辑集中在 isAward 函数中,通过滑窗和状态检查实现条件判断。

四、Python算法源码

以下是 Python 代码的详细注释和讲解,帮助理解每一部分的逻辑和实现。


代码结构

  1. 输入获取
    • 读取输入的记录条数 n
    • 读取每条考勤记录并拆分为列表,存入 records 中。
  2. isAward 函数
    • 核心逻辑,判断单条考勤记录是否满足出勤奖的条件。
  3. getResult 函数
    • 遍历每条考勤记录,调用 isAward 函数判断是否能获得出勤奖。
  4. 算法调用
    • 调用 getResult 函数处理所有记录。

代码逐行注释

# 输入获取
n = int(input())  # 读取记录条数
records = [input().split() for _ in range(n)]  # 读取每条考勤记录并拆分为列表


def isAward(record):
    # 总缺勤次数
    absent = 0

    # 滑窗内正常上班的次数
    present = 0

    # 定义迟到和早退的元组,用于判断连续的迟到/早退
    late_leaveearly = ("late", "leaveearly")

    # 前一次的考勤记录
    preRecord = ""

    # 遍历考勤记录
    for i in range(len(record)):
        # 滑窗长度最大为7,如果超过7,则滑窗的左边界需要右移
        # 滑窗失去的部分是 record[i - 7]
        # 如果失去部分是 present,则更新滑窗内 present 次数
        if i >= 7:
            if "present" == record[i - 7]:
                present -= 1

        # 当前的考勤记录
        curRecord = record[i]

        # 根据当前考勤记录的类型进行处理
        if "absent" == curRecord:
            absent += 1
            # 缺勤超过1次,则拿不到全勤奖
            if absent > 1:
                return "false"
        elif curRecord in late_leaveearly and preRecord in late_leaveearly:
            # 连续的迟到/早退,则拿不到全勤奖
            return "false"
        elif "present" == curRecord:
            # 正常上班,滑窗内 present 次数加1
            present += 1

        # 更新前一次的考勤记录
        preRecord = curRecord

        # 任意连续7次考勤,缺勤/迟到/早退不超过3次
        # 相当于判断:滑窗长度 - present次数 <= 3
        window_len = min(i + 1, 7)  # 滑窗长度
        if window_len - present > 3:
            return "false"

    # 如果所有条件都满足,返回 true
    return "true"


# 算法入口
def getResult():
    # 遍历每条考勤记录,调用 isAward 函数判断是否能获得出勤奖
    for record in records:
        print(isAward(record))


# 算法调用
getResult()

代码逻辑详解

1. 输入获取
  • n = int(input())
    • 读取记录条数 n
  • records = [input().split() for _ in range(n)]
    • 读取每条考勤记录并拆分为列表,存入 records 中。

2. isAward 函数
  • 功能:判断单条考勤记录是否满足出勤奖的条件。
  • 变量说明
    • absent:统计缺勤次数。
    • present:统计滑窗内正常上班的次数。
    • late_leaveearly:定义迟到和早退的元组,用于判断连续的迟到/早退。
    • preRecord:记录前一次的考勤记录,用于判断是否有连续的迟到/早退。
  • 遍历考勤记录
    • 滑窗逻辑
      • 滑窗长度最大为7。
      • 如果当前索引 i >= 7,则滑窗左边界右移,失去的部分是 record[i - 7]
      • 如果失去的部分是 present,则滑窗内 present 次数减1。
    • 当前考勤记录处理
      • absent
        • 缺勤次数加1。
        • 如果缺勤次数 > 1,返回 false
      • lateleaveearly
        • 检查前一次考勤记录是否是 lateleaveearly
        • 如果是,则存在连续的迟到/早退,返回 false
      • present
        • 滑窗内 present 次数加1。
    • 更新前一次考勤记录
      • 将当前考勤记录赋值给 preRecord
    • 滑窗内缺勤/迟到/早退次数检查
      • 计算滑窗长度 window_len(当前索引 + 1,最大为7)。
      • 如果滑窗长度减去 present 次数 > 3,返回 false
  • 返回结果
    • 如果所有条件都满足,返回 true

3. getResult 函数
  • 功能:遍历每条考勤记录,调用 isAward 函数判断是否能获得出勤奖。
  • for record in records:
    • 遍历 records 列表中的每条考勤记录。
    • 调用 isAward 函数判断当前记录是否满足条件。
    • 输出结果(truefalse)。

4. 算法调用
  • getResult()
    • 调用 getResult 函数处理所有记录。

示例运行

输入:
2
present
present absent present present leaveearly present absent
输出:
true
false
解析:
  1. 第一条记录
    • 只有 present,满足所有条件,输出 true
  2. 第二条记录
    • absent 出现2次,不满足条件1。
    • 存在 leaveearlyabsent,但未连续,满足条件2。
    • 滑动窗口检查发现某些窗口内 absentlateleaveearly 的总次数 > 3,不满足条件3。
    • 输出 false

总结

  • 代码通过遍历考勤记录,结合滑动窗口和状态统计,高效判断是否满足出勤奖的条件。
  • 核心逻辑集中在 isAward 函数中,通过滑窗和状态检查实现条件判断。

五、C/C++算法源码:

以下是 C++C语言 版本的代码实现,并附带详细的中文注释和讲解。


C++ 版本

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// 判断两个字符串是否相等
bool eq(const string& a, const string& b) {
    return a == b;
}

// 判断单条考勤记录是否满足出勤奖条件
bool isAward(const vector<string>& records) {
    // 总缺勤次数
    int absent = 0;

    // 滑窗内正常上班的次数
    int present = 0;

    // 记录前一次的考勤记录
    string preRecord = "";

    for (int i = 0; i < records.size(); i++) {
        // 滑窗长度最大为7,如果超过7,则滑窗的左边界需要右移
        // 滑窗失去的部分是 records[i - 7]
        // 如果失去部分是 present,则更新滑窗内 present 次数
        if (i >= 7) {
            if (eq("present", records[i - 7])) present--;
        }

        // 当前的考勤记录
        string curRecord = records[i];

        if (eq(curRecord, "absent")) {
            // 缺勤不超过一次
            if (++absent > 1) return false;
        } else if (eq(curRecord, "late") || eq(curRecord, "leaveearly")) {
            // 没有连续的迟到/早退
            if (eq(preRecord, "late") || eq(preRecord, "leaveearly")) return false;
        } else if (eq(curRecord, "present")) {
            // 正常上班,滑窗内 present 次数加1
            present++;
        }

        // 更新前一次的考勤记录
        preRecord = curRecord;

        // 任意连续7次考勤,缺勤/迟到/早退不超过3次
        // 相当于判断:滑窗长度 - present次数 <= 3
        int window_len = min(i + 1, 7);
        if (window_len - present > 3) return false;
    }

    // 如果所有条件都满足,返回 true
    return true;
}

int main() {
    int n;
    cin >> n; // 读取记录条数
    cin.ignore(); // 忽略换行符

    for (int i = 0; i < n; i++) {
        string line;
        getline(cin, line); // 读取一行考勤记录

        vector<string> records;
        string record;
        for (char ch : line) {
            if (ch == ' ') {
                records.push_back(record);
                record.clear();
            } else {
                record += ch;
            }
        }
        if (!record.empty()) records.push_back(record);

        // 调用 isAward 函数判断是否能获得出勤奖
        cout << (isAward(records) ? "true" : "false") << endl;
    }

    return 0;
}

C语言版本

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

#define MIN(a, b) ((a) < (b) ? (a) : (b))

// 判断两个字符串是否相等
int eq(const char* a, const char* b) {
    return strcmp(a, b) == 0;
}

// 判断单条考勤记录是否满足出勤奖条件
int isAward(char records[][15], int records_size) {
    // 总缺勤次数
    int absent = 0;

    // 滑窗内正常上班的次数
    int present = 0;

    // 记录前一次的考勤记录
    const char* preRecord = "";

    for (int i = 0; i < records_size; i++) {
        // 滑窗长度最大为7,如果超过7,则滑窗的左边界需要右移
        // 滑窗失去的部分是 records[i - 7]
        // 如果失去部分是 present,则更新滑窗内 present 次数
        if (i >= 7) {
            if (eq("present", records[i - 7])) present--;
        }

        // 当前的考勤记录
        const char* curRecord = records[i];

        if (eq(curRecord, "absent")) {
            // 缺勤不超过一次
            if (++absent > 1) return 0;
        } else if (eq(curRecord, "late") || eq(curRecord, "leaveearly")) {
            // 没有连续的迟到/早退
            if (eq(preRecord, "late") || eq(preRecord, "leaveearly")) return 0;
        } else if (eq(curRecord, "present")) {
            // 正常上班,滑窗内 present 次数加1
            present++;
        }

        // 更新前一次的考勤记录
        preRecord = curRecord;

        // 任意连续7次考勤,缺勤/迟到/早退不超过3次
        // 相当于判断:滑窗长度 - present次数 <= 3
        int window_len = MIN(i + 1, 7);
        if (window_len - present > 3) return 0;
    }

    // 如果所有条件都满足,返回 true
    return 1;
}

int main() {
    int n;
    scanf("%d", &n); // 读取记录条数
    getchar(); // 忽略换行符

    for (int i = 0; i < n; i++) {
        char records[10000][15];
        int records_size = 0;

        // 读取一行考勤记录
        while (scanf("%s", records[records_size++])) {
            if (getchar() != ' ') break;
        }

        // 调用 isAward 函数判断是否能获得出勤奖
        puts(isAward(records, records_size) ? "true" : "false");
    }

    return 0;
}

代码逻辑详解

1. 输入获取
  • C++
    • 使用 cin 读取记录条数 n
    • 使用 getline 读取一行考勤记录,并按空格拆分为 vector<string>
  • C语言
    • 使用 scanf 读取记录条数 n
    • 使用 scanfgetchar 读取一行考勤记录,并按空格拆分为二维字符数组。
2. isAward 函数
  • 功能:判断单条考勤记录是否满足出勤奖的条件。
  • 变量说明
    • absent:统计缺勤次数。
    • present:统计滑窗内正常上班的次数。
    • preRecord:记录前一次的考勤记录,用于判断是否有连续的迟到/早退。
  • 遍历考勤记录
    • 滑窗逻辑
      • 滑窗长度最大为7。
      • 如果当前索引 i >= 7,则滑窗左边界右移,失去的部分是 records[i - 7]
      • 如果失去的部分是 present,则滑窗内 present 次数减1。
    • 当前考勤记录处理
      • absent
        • 缺勤次数加1。
        • 如果缺勤次数 > 1,返回 false
      • lateleaveearly
        • 检查前一次考勤记录是否是 lateleaveearly
        • 如果是,则存在连续的迟到/早退,返回 false
      • present
        • 滑窗内 present 次数加1。
    • 更新前一次考勤记录
      • 将当前考勤记录赋值给 preRecord
    • 滑窗内缺勤/迟到/早退次数检查
      • 计算滑窗长度 window_len(当前索引 + 1,最大为7)。
      • 如果滑窗长度减去 present 次数 > 3,返回 false
  • 返回结果
    • 如果所有条件都满足,返回 true
3. 主函数
  • 功能
    • 读取输入数据并解析。
    • 调用 isAward 函数判断每条考勤记录是否能获得出勤奖。
    • 输出结果。

示例运行

输入:
2
present
present absent present present leaveearly present absent
输出:
true
false
解析:
  1. 第一条记录
    • 只有 present,满足所有条件,输出 true
  2. 第二条记录
    • absent 出现2次,不满足条件1。
    • 存在 leaveearlyabsent,但未连续,满足条件2。
    • 滑动窗口检查发现某些窗口内 absentlateleaveearly 的总次数 > 3,不满足条件3。
    • 输出 false

总结

  • 代码通过遍历考勤记录,结合滑动窗口和状态统计,高效判断是否满足出勤奖的条件。
  • 核心逻辑集中在 isAward 函数中,通过滑窗和状态检查实现条件判断。

六、尾言

什么是华为OD?

华为OD(Outsourcing Developer,外包开发工程师)是华为针对软件开发工程师岗位的一种招聘形式,主要包括笔试、技术面试以及综合面试等环节。尤其在笔试部分,算法题的机试至关重要。

为什么刷题很重要?

  1. 机试是进入技术面的第一关:
    华为OD机试(常被称为机考)主要考察算法和编程能力。只有通过机试,才能进入后续的技术面试环节。

  2. 技术面试需要手撕代码:
    技术一面和二面通常会涉及现场编写代码或算法题。面试官会注重考察候选人的思路清晰度、代码规范性以及解决问题的能力。因此提前刷题、多练习是通过面试的重要保障。

  3. 入职后的可信考试:
    入职华为后,还需要通过“可信考试”。可信考试分为三个等级:

    • 入门级:主要考察基础算法与编程能力。
    • 工作级:更贴近实际业务需求,可能涉及复杂的算法或与工作内容相关的场景题目。
    • 专业级:最高等级,考察深层次的算法以及优化能力,与薪资直接挂钩。

刷题策略与说明:

2024年8月14日之后,华为OD机试的题库转为 E卷,由往年题库(D卷、A卷、B卷、C卷)和全新题目组成。刷题时可以参考以下策略:

  1. 关注历年真题:

    • 题库中的旧题占比较大,建议优先刷历年的A卷、B卷、C卷、D卷题目。
    • 对于每道题目,建议深度理解其解题思路、代码实现,以及相关算法的适用场景。
  2. 适应新题目:

    • E卷中包含全新题目,需要掌握全面的算法知识和一定的灵活应对能力。
    • 建议关注新的刷题平台或交流群,获取最新题目的解析和动态。
  3. 掌握常见算法:
    华为OD考试通常涉及以下算法和数据结构:

    • 排序算法(快速排序、归并排序等)
    • 动态规划(背包问题、最长公共子序列等)
    • 贪心算法
    • 栈、队列、链表的操作
    • 图论(最短路径、最小生成树等)
    • 滑动窗口、双指针算法
  4. 保持编程规范:

    • 注重代码的可读性和注释的清晰度。
    • 熟练使用常见编程语言,如C++、Java、Python等。

如何获取资源?

  1. 官方参考:

    • 华为招聘官网或相关的招聘平台会有一些参考信息。
    • 华为OD的相关公众号可能也会发布相关的刷题资料或学习资源。
  2. 加入刷题社区:

    • 找到可信的刷题交流群,与其他备考的小伙伴交流经验。
    • 关注知名的刷题网站,如LeetCode、牛客网等,这些平台上有许多华为OD的历年真题和解析。
  3. 寻找系统性的教程:

    • 学习一本经典的算法书籍,例如《算法导论》《剑指Offer》《编程之美》等。
    • 完成系统的学习课程,例如数据结构与算法的在线课程。

积极心态与持续努力:

刷题的过程可能会比较枯燥,但它能够显著提升编程能力和算法思维。无论是为了通过华为OD的招聘考试,还是为了未来的职业发展,这些积累都会成为重要的财富。

考试注意细节

  1. 本地编写代码

    • 在本地 IDE(如 VS Code、PyCharm 等)上编写、保存和调试代码,确保逻辑正确后再复制粘贴到考试页面。这样可以减少语法错误,提高代码准确性。
  2. 调整心态,保持冷静

    • 遇到提示不足或实现不确定的问题时,不必慌张,可以采用更简单或更有把握的方法替代,确保思路清晰。
  3. 输入输出完整性

    • 注意训练和考试时都需要编写完整的输入输出代码,尤其是和题目示例保持一致。完成代码后务必及时调试,确保功能符合要求。
  4. 快捷键使用

    • 删除行可用 Ctrl+D,复制、粘贴和撤销分别为 Ctrl+CCtrl+VCtrl+Z,这些可以正常使用。
    • 避免使用 Ctrl+S,以免触发浏览器的保存功能。
  5. 浏览器要求

    • 使用最新版的 Google Chrome 浏览器完成考试,确保摄像头开启并正常工作。考试期间不要切换到其他网站,以免影响考试成绩。
  6. 交卷相关

    • 答题前,务必仔细查看题目示例,避免遗漏要求。
    • 每完成一道题后,点击【保存并调试】按钮,多次保存和调试是允许的,系统会记录得分最高的一次结果。完成所有题目后,点击【提交本题型】按钮。
    • 确保在考试结束前提交试卷,避免因未保存或调试失误而丢分。
  7. 时间和分数安排

    • 总时间:150 分钟;总分:400 分。
    • 试卷结构:2 道一星难度题(每题 100 分),1 道二星难度题(200 分)。及格分为 150 分。合理分配时间,优先完成自己擅长的题目。
  8. 考试环境准备

    • 考试前请备好草稿纸和笔。考试中尽量避免离开座位,确保监控画面正常。
    • 如需上厕所,请提前规划好时间以减少中途离开监控的可能性。
  9. 技术问题处理

    • 如果考试中遇到断电、断网、死机等技术问题,可以关闭浏览器并重新打开试卷链接继续作答。
    • 出现其他问题,请第一时间联系 HR 或监考人员进行反馈。

祝你考试顺利,取得理想成绩!


http://www.kler.cn/a/517307.html

相关文章:

  • 【由浅入深认识Maven】第2部分 maven依赖管理与仓库机制
  • 设计新的 Kibana 仪表板布局以支持可折叠部分等
  • kotlin内联函数——runCatching
  • Spring 源码学习(七)——注解后处理器-2
  • golang网络编程
  • 【信息系统项目管理师-选择真题】2018上半年综合知识答案和详解
  • 【leetcode100】二叉树的右视图
  • 职责链模式
  • MES系统和ERP系统有什么区别?
  • Web 渗透测试工具 - SpideyX
  • Mac 上管理本地 Go 版本
  • PHP防伪溯源一体化管理系统小程序
  • 上位机知识篇---return环境变量.bashrc
  • ios打包:uuid与udid
  • 【山东乡镇界】面图层shp格式乡镇名称和编码wgs84坐标无偏移arcgis数据内容测评
  • LLM基础知识
  • B站pwn教程笔记-1
  • 全连接神经网络(前馈神经网络)
  • 二叉树的存储(下)c++
  • Jmeter使用Request URL请求接口
  • docker 安装 redis 详解
  • Jetson Orin Nano Super之pytorch + torchvision安装
  • 在 Windows 11 中设置 WSL2 Ubuntu 的 `networkingMode=mirrored` 详细教程
  • 【C语言】在Windows上为可执行文件.exe添加自定义图标
  • vite端口项目打包后的端口转发问题
  • 基于微信小程序的个人健康管理系统