2025 A卷 100分 題型
本專欄內全部題目均提供Java、python、JavaScript、C、C++、GO六種語言的最佳實現方式;
并且每種語言均涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、3個測試用例以及綜合分析;
本文收錄于專欄:《2025華為OD真題目錄+全流程解析+備考攻略+經驗分享》
華為OD機試真題《考勤信息》:
文章快捷目錄
題目描述及說明
Java
python
JavaScript
C++
C
GO
更多內容
題目名稱:考勤信息
- 知識點:字符串處理、滑動窗口、邏輯判斷
- 時間限制:1秒
- 空間限制:256MB
- 限定語言:不限
題目描述
公司用一個字符串來表示員工的出勤信息,包含以下四種標記:
absent
:缺勤late
:遲到leaveearly
:早退present
:正常上班
出勤獎判定條件:
- 缺勤不超過一次;
- 沒有連續的遲到/早退(即相鄰記錄不能同時為
late
或leaveearly
); - 任意連續7次考勤中,缺勤/遲到/早退的總次數不超過3次。
輸入描述:
- 第一行為記錄條數
N
(N >= 1
); - 后續
N
行為考勤記錄字符串(長度< 10000
,無非法輸入)。
示例:
2
present
present absent present present leaveearly present absent
輸出描述:
對每組考勤記錄,輸出true
(可獲獎)或false
(不可獲獎),結果用空格分隔。
示例輸出:
true false
Java
問題分析
題目要求根據員工的考勤記錄判斷其是否符合獲得出勤獎的條件。需滿足以下三個條件:
- 缺勤不超過一次;
- 沒有連續的遲到或早退;
- 任意連續7次考勤中,違規次數(缺勤/遲到/早退)不超過3次。
解題思路
- 條件一:遍歷所有記錄,統計缺勤次數。若超過1次,直接返回
false
。 - 條件二:遍歷相鄰記錄,若相鄰兩個記錄均屬于遲到或早退,返回
false
。 - 條件三:若記錄數≥7,使用滑動窗口檢查每個連續7次考勤的違規次數。若任何窗口超過3次,返回
false
。
代碼實現
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int N = Integer.parseInt(scanner.nextLine()); // 讀取測試用例數StringBuilder result = new StringBuilder();for (int i = 0; i < N; i++) {int n = Integer.parseInt(scanner.nextLine()); // 讀取當前用例的記錄數String[] records = new String[n];for (int j = 0; j < n; j++) {records[j] = scanner.nextLine().trim(); // 讀取每條記錄}result.append(checkAttendance(records) ? "true " : "false ");}System.out.println(result.toString().trim());scanner.close();}private static boolean checkAttendance(String[] records) {int n = records.length;int absentCount = 0;int[] violations = new int[n]; // 標記是否為違規記錄(absent/late/leaveearly)// 檢查條件1和條件2,并構建violations數組for (int i = 0; i < n; i++) {String record = records[i];// 條件1:統計缺勤次數if (record.equals("absent")) {absentCount++;if (absentCount > 1) return false;}// 構建violations數組(1表示違規)violations[i] = (record.equals("absent") || record.equals("late") || record.equals("leaveearly")) ? 1 : 0;// 條件2:檢查相鄰記錄是否均為遲到/早退if (i > 0) {String prev = records[i - 1];boolean prevViolate = prev.equals("late") || prev.equals("leaveearly");boolean currViolate = record.equals("late") || record.equals("leaveearly");if (prevViolate && currViolate) return false;}}// 條件3:滑動窗口檢查連續7次考勤if (n >= 7) {int windowSum = 0;// 初始化第一個窗口(前7個記錄)for (int j = 0; j < 7; j++) {windowSum += violations[j];}if (windowSum > 3) return false;// 滑動窗口,每次移動一步for (int j = 7; j < n; j++) {windowSum += violations[j] - violations[j - 7];if (windowSum > 3) return false;}}return true;}
}
代碼解析
-
輸入處理:
scanner.nextLine()
讀取輸入,處理多個測試用例。records
數組存儲每個用戶的考勤記錄。
-
條件一檢查:
- 統計
absent
次數,超過1次直接返回false
。
- 統計
-
條件二檢查:
- 遍歷相鄰記錄,若當前和前一個記錄均屬于遲到/早退,返回
false
。
- 遍歷相鄰記錄,若當前和前一個記錄均屬于遲到/早退,返回
-
條件三檢查:
- 構建
violations
數組,標記違規記錄。 - 使用滑動窗口計算每個連續7次考勤的違規次數總和。
- 若任何窗口總和超過3,返回
false
。
- 構建
示例測試
-
示例輸入1:
輸入:2 present present absent present present leaveearly present absent
輸出:
true false
解釋:- 第一個用例無缺勤且滿足所有條件。
- 第二個用例缺勤兩次,違反條件一。
-
測試用例2:
輸入:1 late leaveearly
輸出:
false
解釋:相鄰記錄均為遲到/早退,違反條件二。 -
測試用例3:
輸入:7 absent late late present present present present
輸出:
false
解釋:連續7次考勤中違規次數為3(absent + 2次late),滿足條件三。
綜合分析
-
時間復雜度:
- O(N),其中N為記錄數。每個記錄僅遍歷兩次(條件檢查+滑動窗口)。
-
空間復雜度:
- O(N),存儲考勤記錄和違規標記數組。
-
正確性:
- 嚴格按題意分步驟檢查三個條件,確保邏輯正確。
-
優勢:
- 高效性:滑動窗口將條件三的時間復雜度優化為O(N)。
- 可讀性:代碼結構清晰,條件處理明確。
-
適用性:
- 完全支持題目約束(記錄數≤1e5),滿足時間和空間要求。
python
問題分析
題目要求判斷員工的考勤記錄是否符合出勤獎條件,需滿足以下三個條件:
- 缺勤不超過一次(
absent
次數 ≤ 1); - 無連續遲到/早退(相鄰記錄不能同為
late
或leaveearly
); - 任意連續7次考勤中違規次數(缺勤、遲到、早退)不超過3次。
解題思路
- 條件一:統計所有記錄中
absent
的次數,若超過1次直接判定失敗。 - 條件二:遍歷相鄰記錄,檢查是否存在連續的
late
或leaveearly
。 - 條件三:使用滑動窗口檢查所有長度為7的連續窗口,統計違規次數是否超過3次。
代碼實現
import sysdef check_attendance(records):# 條件一:缺勤次數不超過1次absent_count = records.count('absent')if absent_count > 1:return False# 條件二:檢查相鄰記錄是否均為遲到/早退for i in range(