考勤信息

题目描述

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

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

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

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

输入描述

用户的考勤数据字符串:

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

如:

2
present
present absent present present leaveearly present absent

输出描述

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

true false

示例1

输入:

2
present
present present

输出:

true true

示例2

输入:

2
present
present absent present present leaveearly present absent

输出:

true false

题解

Python

import sys

def main():
    def to_state(s: str) -> int:
        if s == "absent":
            return ABSENT
        elif s == "late":
            return LATE
        elif s == "leaveearly":
            return LEAVE_EARLY
        elif s == "present":
            return PRESENT
        else:
            assert False, "Invalid state"
    ABSENT = 0
    LATE = 1
    LEAVE_EARLY = 2
    PRESENT = 3

    # 先解析出所有的出勤记录
    num_person = int(input())
    person_presents = []
    for line in sys.stdin.readlines():
        person = list(map(to_state, line.split()))
        person_presents.append(person)
    assert num_person == len(person_presents)

    # 然后基于三条规则, 过滤是否都成立
    # 如果有一条不成立, 就返回 false
    # 否则返回 true
    person_awards  = []
    for person_present in person_presents:
        award = True
        # 缺勤
        if person_present.count(ABSENT) > 1:
            award = False
        # 没有连续的迟到/早退
        for i in range(len(person_present) - 1):
            if person_present[i] in (LATE, LEAVE_EARLY) and person_present[i + 1] in (LATE, LEAVE_EARLY):
                award = False
                break

        # 连续7次考勤, 迟到/早退/缺勤不超过3次
        if len(person_present) > 7:
            # 如果多于7次考勤, 就用滑动窗口的方式遍历所有考勤
            for i in range(len(person_present) - 7):
                if person_present[i:i+7].count(PRESENT) < 4:
                    award = False
                    break
        else:
            # 否则就只计算所有考勤
            if person_present.count(ABSENT) + person_present.count(LATE) + person_present.count(LEAVE_EARLY) > 3:
                award = False


        person_awards.append(award)

    # 输出结果
    print(" ".join("true" if award else "false" for award in person_awards))

if __name__ == "__main__":
    main()