返回目录

题目描述

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

  • absent:缺勤
  • late:迟到
  • leaveearly:早退
  • present:正常上班

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

  • 缺勤不超过一次;
  • 没有连续的迟到/早退;
  • 任意连续7次考勤,缺勤/迟到/早退不超过3次。

输入描述

用户的考勤数据字符串

  • 记录条数 >= 1;
  • 输入字符串长度 < 10000;
  • 不存在非法输入;

如:

2
present
present absent present present leaveearly present absent

输出描述

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

true false

示例:

输入2
present
present present
输出true true
说明

Python算法源码

def get_result(n, records):
    results = []
    for record in records:
        results.append(str(is_award(record)).lower())
    print(" ".join(results))


def is_award(record):
    # 总缺勤次数
    absent = 0

    # 滑窗内正常上班的次数
    present = 0

    # 记录前一次的考勤记录
    pre_record = ""

    for i in range(len(record)):
        if i >= 7:
            # 滑窗长度最大为7,如果超过7,则滑窗的左边界需要右移, 滑窗失去的部分record[i - 7]
            # 如果失去部分是present,则更新滑窗内present次数
            if record[i - 7] == "present":
                present -= 1

        # 当前的考勤记录
        cur_record = record[i]

        if cur_record == "absent":
            # 缺勤不超过一次
            absent += 1
            if absent > 1:
                return False
        elif cur_record == "late" or cur_record == "leaveearly":
            # 没有连续的迟到/早退
            if pre_record == "late" or pre_record == "leaveearly":
                return False
        elif cur_record == "present":
            present += 1

        pre_record = cur_record

        # 任意连续7次考勤,缺勤/迟到/早退不超过3次, 相当于判断: 滑窗长度 - present次数 <= 3
        window_len = min(i + 1, 7)  # 滑窗长度
        if window_len - present > 3:
            return False

    return True


if __name__ == "__main__":
    n = int(input())
    records = []
    for _ in range(n):
        records.append(input().split())

    get_result(n, records)

C算法源码

#include <stdio.h>
#include <string.h>

#define MAX_RECORD_LENGTH 100 // 最大记录长度
#define MAX_WINDOW_LENGTH 7   // 最大滑窗长度

char *is_award(char records[][MAX_RECORD_LENGTH], int record_count);
void get_result(char records[][MAX_RECORD_LENGTH], int n);

int main() {
    int n;
    scanf("%d", &n);
    getchar(); // 消耗换行符

    char records[n][MAX_RECORD_LENGTH];

    for (int i = 0; i < n; i++) {
        fgets(records[i], MAX_RECORD_LENGTH, stdin);
        records[i][strcspn(records[i], "\n")] = '\0'; // 去除换行符
    }

    get_result(records, n);

    return 0;
}

void get_result(char records[][MAX_RECORD_LENGTH], int n) {
    for (int i = 0; i < n; i++) {
        char *result = is_award(records, i);
        printf("%s ", result);
    }
    printf("\n");
}

char *is_award(char records[][MAX_RECORD_LENGTH], int record_count) {
    // 总缺勤次数
    int absent = 0;

    // 滑窗内正常上班的次数
    int present = 0;

    // 记录前一次的考勤记录
    char preRecord[MAX_RECORD_LENGTH] = "";

    for (int i = 0; i < record_count; i++) {
        if (i >= MAX_WINDOW_LENGTH) {
            // 滑窗长度最大为7,如果超过7,则滑窗的左边界需要右移, 滑窗失去的部分record[i - 7]
            // 如果失去部分是present,则更新滑窗内present次数
            if (strcmp(records[i - 7], "present") == 0) present--;
        }

        // 当前的考勤记录
        char curRecord[MAX_RECORD_LENGTH];
        strcpy(curRecord, records[i]);

        if (strcmp(curRecord, "absent") == 0) {
            // 缺勤不超过一次
            if (++absent > 1) return "false";
        } else if (strcmp(curRecord, "late") == 0 || strcmp(curRecord, "leaveearly") == 0) {
            // 没有连续的迟到/早退
            if (strcmp(preRecord, "late") == 0 || strcmp(preRecord, "leaveearly") == 0) return "false";
        } else if (strcmp(curRecord, "present") == 0) {
            present++;
        }

        strcpy(preRecord, curRecord);

        // 任意连续7次考勤,缺勤/迟到/早退不超过3次, 相当于判断: 滑窗长度 - present次数 <= 3
        int window_len = (i + 1) < MAX_WINDOW_LENGTH ? (i + 1) : MAX_WINDOW_LENGTH; // 滑窗长度
        if (window_len - present > 3) return "false";
    }

    return "true";
}

Java算法源码

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();

        scanner.nextLine(); // Consume newline
        for (int i = 0; i < n; i++) {
            String s = scanner.nextLine();

            List<String> records = new ArrayList<>();
            StringTokenizer st = new StringTokenizer(s);
            while (st.hasMoreTokens()) {
                records.add(st.nextToken());
            }

            System.out.print(isAward(records) + " ");
        }

        System.out.println();
    }

    public static String isAward(List<String> records) {
        // 总缺勤次数
        int absent = 0;

        // 滑窗内正常上班的次数
        int present = 0;

        // 记录前一次的考勤记录
        String preRecord = "";

        for (int i = 0; i < records.size(); i++) {
            if (i >= 7) {
                // 滑窗长度最大为7,如果超过7,则滑窗的左边界需要右移, 滑窗失去的部分record[i - 7]
                // 如果失去部分是present,则更新滑窗内present次数
                if ("present".equals(records.get(i - 7))) present--;
            }

            // 当前的考勤记录
            String curRecord = records.get(i);

            if ("absent".equals(curRecord)) {
                // 缺勤不超过一次
                if (++absent > 1) return "false";
            } else if ("late".equals(curRecord) || "leaveearly".equals(curRecord)) {
                // 没有连续的迟到/早退
                if ("late".equals(preRecord) || "leaveearly".equals(preRecord)) return "false";
            } else if ("present".equals(curRecord)) {
                present++;
            }

            preRecord = curRecord;

            // 任意连续7次考勤,缺勤/迟到/早退不超过3次, 相当于判断: 滑窗长度 - present次数 <= 3
            int windowLen = Math.min(i + 1, 7); // 滑窗长度
            if (windowLen - present > 3) return "false";
        }

        return "true";
    }
}
最后修改:2024 年 04 月 03 日
如果觉得我的文章对你有用,请随意赞赏