10. 考勤信息

80 阅读2分钟

题目描述

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

  • 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
说明
输入2 present present absent present present leaveearly present absent
输出true false
说明

C++源码

#include <iostream>
#include <vector>
#include <sstream>
using namespace std;

string isAward(const vector<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" == records[i - 7]) present--;
        }

        // 当前的考勤记录
        string curRecord = records[i];

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

        preRecord = curRecord;

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

int main() {
    int n;
    cin >> n;
    cin.ignore();
    for (int i = 0; i < n; i++) {
        string s;
        getline(cin, s);

        stringstream ss(s);
        string token;

        vector<string> records;

        while (getline(ss, token, ' ')) {
            records.emplace_back(token);
        }

        cout << isAward(records) << " ";
    }
    return 0;
}