华为OD E卷(100分)37-考勤信息
前言
工作了十几年,从普通的研发工程师一路成长为研发经理、研发总监。临近40岁,本想辞职后换一个相对稳定的工作环境一直干到老, 没想到离职后三个多月了还没找到工作,愁肠百结。为了让自己有点事情做,也算提高一下自己的编程能力,无聊之余打算用一些大厂的编程题练练手。希望通过这些分享能够帮到一些人,也希望能和看到此文的大神们沟通交流,提升自己,更希望在此期间能够找到一份理想的工作。
题目描述
K小姐是一家公司的人力资源经理,他需要根据员工的出勤记录来决定是否发放考勤奖励。公司规定了以下出勤状态:
- absent:缺勤
- late:迟到
- leaveearly:早退
- present:正常出勤
员工获得考勤奖励需满足以下全部条件:
- 缺勤次数不超过 1 次;
- 没有连续的迟到或早退;
- 任意连续7 天内,缺勤、迟到和早退的次数总和不超过 3 次。
请你帮助K小姐编写一个程序,判断每位员工是否能获得考勤奖励。
输入
第一行包含一个正整数n,表示员工的总数。
接下来 n 行,每行包含若干个空格分隔的字符串,表示一名员工的出勤记录。
输出
输出n 行,每行为 true 或 false,表示对应的员工是否能获得考勤奖励。
示例
示例1
输入
2
present
present present
输出true
true说明
两名员工的出勤记录都满足获得奖励的条件,因此输出两个 true。
示例2
输入
2
present
present absent present present leaveearly present absent
输出true
false说明
第一名员工满足条件,输出 true。第二名员工有 2 次缺勤,不满足条件 1,因此输出 false。
数据范围
1≤n≤100
每个员工的出勤记录不超过1000 条。
解题思路
滑动窗口。
题解
Java实现
package huawei.e100;
import java.util.Scanner;
/**
* @author arnold
* @date 2024年12月24日
* 考勤信息
*/
public class T37 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
int n = sc.nextInt();
sc.nextLine();
for (int i = 0; i < n; i++) {
String[] kq = sc.nextLine().split(" ");
boolean res = run(kq);
if (res) {
System.out.println("true");
} else{
System.out.println("false");
}
}
}
}
/** 计算考勤是否能得到奖励
缺勤次数不超过 1 次;
没有连续的迟到或早退;
任意连续7 天内,缺勤、迟到和早退的次数总和不超过 3 次。
*/
static boolean run(String[] kq) {
boolean prepresent = true;
for (int i = 0; i < kq.length; i++) {
int nopresentTime = 0;
// 7天时间窗滑块
for (int j = i; j < kq.length && j < i+7; j++) {
if(kq[j].equals("absent")) {
return false; //缺勤
} else if (kq[j].equals("late") || kq[j].equals("leaveearly")) {
if (prepresent == false) {
return false; //连续的迟到或早退
} else {
nopresentTime++;
prepresent = false;
}
} else {
prepresent = true;
}
}
if (nopresentTime > 3) {
return false; //任意连续7 天内,缺勤、迟到和早退的次数总和超过 3 次
}
}
return true;
}
}