#P3036. 考勤信息(100分)
-
1000ms
Tried: 292
Accepted: 52
Difficulty: 4
所属公司 :
华为od
-
算法标签>模拟
考勤信息(100分)
思路:滑动窗口模拟
维护一个长度为7的窗口,并统计其缺勒/迟到/早退次数是否超过3,维护一个变量,统计其缺勤次数,并在所有下标>0的位置判断是否有连续的迟到/早退,如果都没有,则返回true,有任意一点不满足,返回false。写的时候最好写一个判断函数,这样会方便一些。
JavaScript
// 引入readline模块
const readline = require('readline');
// 创建readline接口,设置输入和输出
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// 定义考勤信息映射
const mp = {
"absent": 0,
"late": 1,
"leaveearly": 2,
"present": 3
};
// 定义检查函数,判断考勤信息是否合法
function check(s) {
// 统计每种考勤状态出现的次数
const cnts = Array(4).fill(0);
const m = s.length;
// 遍历考勤信息
for (let i = 0; i < m; i++) {
// 增加当前考勤状态的计数
cnts[mp[s[i]]]++;
// 如果考勤信息长度超过7,减少七天前的考勤状态计数
if (i > 6) {
cnts[mp[s[i - 7]]]--;
}
// 如果考勤信息长度大于等于7,并且正常上班天数小于4,返回false
if (i >= 6 && cnts[3] < 4) {
return false;
}
// 如果不是第一个考勤信息,并且连续两天都是迟到或早退,返回false
if (i > 0 && 1 <= mp[s[i]] && mp[s[i]] <= 2 && 1 <= mp[s[i - 1]] && mp[s[i - 1]] <= 2) {
return false;
}
}
// 统计所有缺勤的次数
let count = 0;
for (const x of s) {
if (mp[x] === 0) {
count++;
}
}
// 缺勤次数不超过1时返回true,否则返回false
return count <= 1;
}
// 初始化变量
let n; // 测试用例数量
let currentTest = 0; // 当前测试用例序号
// 监听输入的每一行
rl.on('line', (line) => {
if (!n) {
// 第一行输入为测试用例数量
n = parseInt(line);
} else {
// 处理后续测试用例
const s = line.split(' ');
// 调用check函数检查考勤信息是否合法,并输出结果
if (check(s)) {
console.log("true");
} else {
console.log("false");
}
// 增加当前测试用例序号,当序号达到测试用例数量时关闭rl接口
currentTest++;
if (currentTest === n) {
rl.close();
}
}
});
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine(); // 消耗掉换行符
while (n-- > 0) {
String[] s = scanner.nextLine().split(" ");
if (check(s)) {
System.out.println("true");
} else {
System.out.println("false");
}
}
}
static boolean check(String[] s) {
int[] cnts = new int[4];
int m = s.length;
// 初始化考勤信息映射
Map<String, Integer> mp = new HashMap<>();
mp.put("absent", 0);
mp.put("late", 1);
mp.put("leaveearly", 2);
mp.put("present", 3);
for (int i = 0; i < m; i++) {
cnts[mp.get(s[i])]++;
if (i > 6) {
cnts[mp.get(s[i - 7])]--;
}
if (i >= 6 && cnts[3] < 4) {
return false;
}
if (i > 0 && 1 <= mp.get(s[i]) && mp.get(s[i]) <= 2 && 1 <= mp.get(s[i - 1]) && mp.get(s[i - 1]) <= 2) {
return false;
}
}
int count = 0;
for (String x : s) {
if (mp.get(x) == 0) {
count++;
}
}
return count <= 1;
}
}
Python
mp={"absent":0,"late":1,"leaveearly":2,"present":3} #出勤信息映射
def check(s):
cnts=[0]*4 #统计每一项的次数
m=len(s)
for i in range(m):
cnts[mp[s[i]]]+=1
if i>6:
cnts[mp[s[i-7]]]-=1
if i>=6 and cnts[3]<4: #正常上班天数<4,则说明其他天数超过3次
return False
if i and 1<=mp[s[i]]<=2 and 1<=mp[s[i-1]]<=2: #连续的迟到,早退
return False
count=0 #单独统计所有的缺勤次数
for x in s:
if mp[x]==0:
count+=1
return count<=1
n=int(input())
for _ in range(n):
s=input().split(' ')
if check(s):
print("true")
else:
print("false")
C++
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
// 定义考勤信息映射
unordered_map<string, int> mp = {{"absent", 0}, {"late", 1}, {"leaveearly", 2}, {"present", 3}};
// 检查考勤信息是否合法的函数
bool check(const vector<string>& s) {
// 统计每种考勤状态出现的次数
vector<int> cnts(4, 0);
int m = s.size();
// 遍历考勤信息
for (int i = 0; i < m; i++) {
// 增加当前考勤状态的计数
cnts[mp[s[i]]]++;
// 如果考勤信息长度超过7,减少七天前的考勤状态计数
if (i > 6) {
cnts[mp[s[i - 7]]]--;
}
// 如果考勤信息长度大于等于7,并且正常上班天数小于4,返回false
if (i >= 6 && cnts[3] < 4) {
return false;
}
// 如果不是第一个考勤信息,并且连续两天都是迟到或早退,返回false
if (i > 0 && 1 <= mp[s[i]] && mp[s[i]] <= 2 && 1 <= mp[s[i - 1]] && mp[s[i - 1]] <= 2) {
return false;
}
}
// 统计所有缺勤的次数
int count = 0;
for (const string& x : s) {
if (mp[x] == 0) {
count++;
}
}
// 缺勤次数不超过1时返回true,否则返回false
return count <= 1;
}
int main() {
int n;
cin >> n;
cin.ignore(); // 消耗掉换行符
// 处理每个测试用例
while (n--) {
string line;
getline(cin, line);
vector<string> s;
// 分割字符串得到考勤信息
size_t pos = 0, next;
while ((next = line.find(' ', pos)) != string::npos) {
s.push_back(line.substr(pos, next - pos));
pos = next + 1;
}
s.push_back(line.substr(pos));
// 调用check函数检查考勤信息是否合法,并输出结果
if (check(s)) {
cout << "true" << endl;
} else {
cout << "false" << endl;
}
}
return 0;
}
题目描述
公司用一个字符串来表示员工的出勤信息
- absent:缺勒
- late: 迟到
- leaveearly: 早退
- present: 正常上班
现需根据员工出勤信息,判断本次是否能获得出勤奖,能获得出勤奖的条件如下:
- 缺勤不超过一次,
- 没有连续的迟到/早退:
- 任意连续7次考勤,缺勒/迟到/早退不超过3次
输入描述
第一行输入一个整数n,表示有多少个员工
后面n行,每一行输入若干个字符串,表示第i名员工的出勤信息
输出描述
输出n行,每一行表示这名员工能否获得出勤奖,如果可以,则输出“true",否则输出”false"
样例1
输入
2
present
present present
输出
true
true
样例2
输入
2
present
present absent present present leaveearly present absent
输出
true
false