一、题目描述
公司用一个字符串来标识员工的出勤信息
- absent:缺勤
- late:迟到
- leaveearly:早退
- present:正常上班
现需根据员工出勤信息,判断本次是否能获得出勤奖,能获得出勤奖的条件如下:
- 缺勤不超过1次
- 没有连续的迟到/早退
- 任意连续7次考勤 缺勤/迟到/早退 不超过3次。
二、输入描述
用户的考勤数据字符串记录条数 >=1
输入字符串长度 <10000 ;
不存在非法输入
如:
2
present
present absent present present leaveearly present absent
三、输出描述
根据考勤数据字符串,如果能得到考勤奖输出true否则输出false,对于输出示例的结果应为true false
四、解题思路
题目要求根据员工的出勤信息判断是否能获得出勤奖,需要满足以下条件:
- 缺勤不超过1次;
- 没有连续的迟到或早退;
- 任意连续7次考勤中,缺勤、迟到或早退的次数不超过3次。
算法流程:
- 读取输入的考勤数据字符串记录条数 n;
- 创建一个字符串数组 records,用于存储每条考勤数据字符串;
- 遍历输入,依次读取每条考勤数据字符串,将其存储到 records 数组中;
- 创建一个 ArrayList 对象 res,用于存储每条考勤数据字符串是否能获得出勤奖的结果;
- 遍历 records数组,对每条考勤数据字符串进行如下操作,调用 extracted 方法判断该条考勤数据字符串是否能获得出勤奖,并将结果转换为字符串类型添加到 res 中;
- 将 res 中存储的结果转换为字符串并输出。
五、Java算法源码
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine();
String[] records = new String[n];
for (int i = 0; i < n; i++) {
records[i] = scanner.nextLine();
}
ArrayList<String> res = new ArrayList<>(n);
for (String record : records) {
res.add(String.valueOf(extracted(record.split(" "))));
}
System.out.println(String.join(" ", res));
}
private static boolean extracted(String[] s) {
// 1.缺勤不超过1次
for (int j = 0; j < s.length; j++) {
if ("absent".equals(s[j])) {
return false;
}
}
// 2.没有连续的迟到/早退
if (s.length >= 2) {
for (int i = 1; i < s.length; i++) {
String yesterday = s[i - 1];
String today = s[i];
if (("late".equals(yesterday) || "leaveearly".equals(yesterday))
&& ("late".equals(today) || "leaveearly".equals(today))) {
return false;
}
}
}
// 3.任意连续7次考勤 缺勤/迟到/早退 不超过3次
if (s.length >= 7) {
for (int i = 0; i < s.length; i++) {
int count = 0;
if (i + 7 > s.length) {
break;
}
for (int j = i; j < i + 7; j++) {
String today = s[j];
if ("absent".equals(today) || "late".equals(today) || "leaveearly".equals(today)) {
count++;
if (count >= 3) {
return false;
}
}
}
}
}
return true;
}
六、JavaScript算法源码
// 主函数,程序入口
function main() {
// 创建一个readline接口对象,用于从标准输入读取数据
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// 读取用户输入的第一个整数n
rl.question('请输入一个整数n: ', (n) => {
// 忽略换行符
rl.question('', (ignored) => {
// 创建一个空数组,用于存储记录
const records = [];
// 循环读取n行数据,存入records数组
for (let i = 0; i < parseInt(n); i++) {
rl.question('', (record) => {
records.push(record);
// 如果已经读取了n行数据,则处理数据并输出结果
if (records.length === parseInt(n)) {
// 创建一个空数组,用于存储处理后的结果
const res = [];
// 遍历每条记录,对每条记录进行extracted处理,并将结果存入res数组
for (const record of records) {
res.push(String(extracted(record.split(' '))));
}
// 将结果数组中的字符串用空格拼接,并输出
console.log(res.join(' '));
// 关闭readline接口对象
rl.close();
}
});
}
});
});
}
// extracted函数,用于检查记录是否满足条件
function extracted(s) {
// 1. 检查缺勤次数是否不超过1次
let absentCount = 0;
for (const word of s) {
if (word === 'absent') {
absentCount++;
if (absentCount > 1) {
return false;
}
}
}
// 2. 检查是否没有连续的迟到/早退
for (let i = 1; i < s.length; i++) {
const yesterday = s[i - 1];
const today = s[i];
if ((yesterday === 'late' || yesterday === 'leaveearly') && (today === 'late' || today === 'leaveearly')) {
return false;
}
}
// 3. 检查任意连续7次考勤中缺勤/迟到/早退的次数是否不超过3次
for (let i = 0; i <= s.length - 7; i++) {
let count = 0;
for (let j = i; j < i + 7; j++) {
const today = s[j];
if (today === 'absent' || today === 'late' || today === 'leaveearly') {
count++;
if (count >= 3) {
return false;
}
}
}
}
// 如果满足所有条件,则返回true
return true;
}
// 调用主函数,开始执行程序
main();
七、Python算法源码
# 导入需要的库
from typing import List
# 主函数
def main():
# 读取用户输入的整数n
n = int(input())
# 读取用户输入的换行符,忽略它
input()
# 初始化记录列表
records = []
# 读取n行数据,每行数据作为字符串存入records列表
for _ in range(n):
records.append(input())
# 初始化结果列表
res = []
# 遍历每条记录,对每条记录进行extracted处理,并将结果转为字符串存入res列表
for record in records:
res.append(str(extracted(record.split())))
# 将结果列表中的字符串用空格拼接,并输出
print(' '.join(res))
# extracted函数,用于检查记录是否满足条件
def extracted(s: List[str]) -> bool:
# 1. 检查缺勤次数是否不超过1次
absent_count = sum(1 for word in s if word == 'absent')
if absent_count > 1:
return False
# 2. 检查是否没有连续的迟到/早退
for i in range(1, len(s)):
yesterday = s[i - 1]
today = s[i]
if (yesterday in ['late', 'leaveearly']) and (today in ['late', 'leaveearly']):
return False
# 3. 检查任意连续7次考勤中缺勤/迟到/早退的次数是否不超过3次
for i in range(len(s) - 6):
count = 0
for j in range(i, i + 7):
today = s[j]
if today in ['absent', 'late', 'leaveearly']:
count += 1
if count >= 3:
return False
# 如果满足所有条件,则返回True
return True
# 执行主函数
if __name__ == "__main__":
main()
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 定义最大记录数
#define MAX_RECORDS 100
// extracted 函数,用于检查记录是否满足条件
bool extracted(char **s, int length) {
// 1. 缺勤不超过1次
int absentCount = 0;
for (int j = 0; j < length; j++) {
if (strcmp(s[j], "absent") == 0) {
absentCount++;
if (absentCount > 1) {
return false;
}
}
}
// 2. 没有连续的迟到/早退
if (length >= 2) {
for (int i = 1; i < length; i++) {
char *yesterday = s[i - 1];
char *today = s[i];
if ((strcmp(yesterday, "late") == 0 || strcmp(yesterday, "leaveearly") == 0) &&
(strcmp(today, "late") == 0 || strcmp(today, "leaveearly") == 0)) {
return false;
}
}
}
// 3. 任意连续7次考勤中缺勤/迟到/早退的次数不超过3次
for (int i = 0; i <= length - 7; i++) {
int count = 0;
for (int j = i; j < i + 7; j++) {
char *today = s[j];
if (strcmp(today, "absent") == 0 || strcmp(today, "late") == 0 || strcmp(today, "leaveearly") == 0) {
count++;
if (count >= 3) {
return false;
}
}
}
}
// 如果满足所有条件,返回true
return true;
}
int main() {
char *records[MAX_RECORDS];
int n;
// 读取用户输入的记录数
printf("请输入记录数n: ");
scanf("%d", &n);
getchar(); // 读取换行符
// 读取n行记录
for (int i = 0; i < n; i++) {
char *line = (char *)malloc(100 * sizeof(char)); // 假设每行记录不超过100个字符
if (line == NULL) {
perror("Memory allocation failed");
return 1;
}
if (fgets(line, 100, stdin) == NULL) {
perror("Failed to read line");
return 1;
}
records[i] = line;
}
// 分割每行记录并检查是否符合条件
bool results[n];
for (int i = 0; i < n; i++) {
char *token = strtok(records[i], " ");
int count = 0;
while (token != NULL) {
char *temp = (char *)malloc(strlen(token) + 1);
strcpy(temp, token);
records[i + count] = temp;
token = strtok(NULL, " ");
count++;
}
results[i] = extracted(records + i, count);
}
// 输出结果
for (int i = 0; i < n; i++) {
printf("%s", results[i] ? "true" : "false");
if (i < n - 1) {
printf(" ");
}
}
printf("\n");
// 释放内存
for (int i = 0; i < n; i++) {
free(records[i]);
}
return 0;
}
九、C++算法源码
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
using namespace std;
// 主函数入口
int main(int argc, char** argv) {
// 创建输入流对象
stringstream ss;
string line;
getline(cin, line); // 读取整行输入,包括空格
ss << line; // 将整行输入存入stringstream中
int n;
ss >> n; // 从stringstream中提取整数n
ss.ignore(); // 忽略换行符
// 创建字符串数组来存储记录
vector<string> records(n);
for (int i = 0; i < n; ++i) {
getline(cin, records[i]); // 读取每行记录
}
// 创建vector来存储结果
vector<string> res;
for (const string& record : records) {
// 将提取结果转换为字符串并添加到结果vector中
res.push_back(to_string(extracted(split(record, " "))));
}
// 输出结果,用空格连接
for (size_t i = 0; i < res.size(); ++i) {
cout << res[i];
if (i < res.size() - 1) {
cout << " ";
}
}
cout << endl;
return 0;
}
// 辅助函数,将字符串按分隔符分割为字符串数组
vector<string> split(const string& s, char delimiter) {
vector<string> tokens;
string token;
istringstream tokenStream(s);
while (getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
// 提取函数,根据条件判断记录是否满足要求
bool extracted(const vector<string>& s) {
// 1. 缺勤不超过1次
int absentCount = 0;
for (const string& str : s) {
if (str == "absent") {
absentCount++;
if (absentCount > 1) {
return false;
}
}
}
// 2. 没有连续的迟到/早退
for (size_t i = 1; i < s.size(); ++i) {
const string& yesterday = s[i - 1];
const string& today = s[i];
if ((yesterday == "late" || yesterday == "leaveearly") &&
(today == "late" || today == "leaveearly")) {
return false;
}
}
// 3. 任意连续7次考勤中,缺勤/迟到/早退不超过3次
for (size_t i = 0; i <= s.size() - 7; ++i) {
int count = 0;
for (size_t j = i; j < i + 7; ++j) {
const string& today = s[j];
if (today == "absent" || today == "late" || today == "leaveearly") {
count++;
if (count >= 3) {
return false;
}
}
}
}
return true;
}