华为OD机试 - 根据员工出勤信息,判断本次是否能获得出勤奖(Java & JS & Python & C & C++)

一、题目描述

公司用一个字符串来标识员工的出勤信息

  1. absent:缺勤
  2. late:迟到
  3. leaveearly:早退
  4. present:正常上班

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

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

二、输入描述

用户的考勤数据字符串记录条数 >=1

输入字符串长度 <10000 ;

不存在非法输入

如:

2
present
present absent present present leaveearly present absent

三、输出描述

根据考勤数据字符串,如果能得到考勤奖输出true否则输出false,对于输出示例的结果应为true false

四、解题思路

题目要求根据员工的出勤信息判断是否能获得出勤奖,需要满足以下条件:

  1. 缺勤不超过1次;
  2. 没有连续的迟到或早退;
  3. 任意连续7次考勤中,缺勤、迟到或早退的次数不超过3次。

算法流程:

  1. 读取输入的考勤数据字符串记录条数 n;
  2. 创建一个字符串数组 records,用于存储每条考勤数据字符串;
  3. 遍历输入,依次读取每条考勤数据字符串,将其存储到 records 数组中;
  4. 创建一个 ArrayList 对象 res,用于存储每条考勤数据字符串是否能获得出勤奖的结果;
  5. 遍历 records数组,对每条考勤数据字符串进行如下操作,调用 extracted 方法判断该条考勤数据字符串是否能获得出勤奖,并将结果转换为字符串类型添加到 res 中;
  6. 将 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;  
}
  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值