【力扣刷题笔记第四期】系统设计题

一、招聘策略

某次招聘活动中,共有 deptNum 个部门在招人,每个部门都设定了自己的:招聘目标人数、机考和技面的最低分要求。共有 candidateNum 个应聘者,每个应聘者都有两项能力值:机考分数和技面分数。

招聘规则如下:

  • 选人规则:首先达到部门的门槛要求,即机考和技面分数均大于等于对应最低分要求;然后选人:优先录取技面分数较高的;若技面分数相同,则录取机考分数较高的;若机考分数也相同,则录取应聘者编号较小的。
  • 先进行常规录取,此阶段采用轮询录取方式,以完成招聘目标:
    • 每一轮按部门编号从小到大轮询,部门遵照选人规则录取一人,若无符合要求者则放弃;若已招满(或已无人可录),不再选人;
    • 不断轮询,直至所有部门都完成招聘目标(但不能超过)、或未招满但已无人可录。
  • 在常规录取阶段结束后,各部门均尝试进行一次补录,但最多补录一人(即可能比招聘目标多一人):
    • 按部门编号从小到大的顺序进行补录;
    • 如果还有应聘者与该部门常规录取的最后一名应聘者能力相同(即机考和技面分数均相同),则部门参照选人规则补录一人即结束招聘(即使未成功补录,也结束招聘)。

现给出部门的招聘需求deptDemands,以及应聘者的信息 candidateAbilities。请按部门编号从小到大依次输出所录取人员,部门内所录取人员按录取顺序输出(若无录取人员,输出空序列 [])。

输入

第一行的整数表示招聘部门个数 deptNum,1 <= deptNum <= 10
随后 deptNum 行依次表示每个部门的要求,记录于 deptDemands 数组中,deptDemands[i] 表示编号为 i 的部门的目标人数 机考最低分 技面最低分,目标人数范围 [1, 200],最低分范围 [100, 150]

接下来一行的整数表示应聘者数量 candidateNum,1 <= candidateNum <= 10000
随后 candidateNum 行依次表示每个应聘者的信息,记录于数组 candidateAbilities 中,candidateAbilities[j] 表示编号为 j 的应聘者的机考分数 技面分数,机考和技面分数取值范围 [100, 200]

输出

按部门编号从小到大,每行输出一个部门所录取人员的编号;若没有录取人员,输出空序列 [] 。

样例

输入样例 1 

2
2 130 120
1 150 150
6
150 100
160 190
150 200
200 190
160 190
160 190

输出样例 1

[2 1 4]
[3]

提示样例 1

招聘录取过程解释如下:

  • 第一轮:按部门编号从小到大,部门0 先选人,按选人规则优先录取了应聘者2 。然后部门1选人,优先录取了应聘者 3 ,部门1招满、退出轮询。
  • 第二轮:部门0 选人,应聘者1、4、5 的能力值都相同,录取编号小的应聘者1 。

    两轮后部门0 和 部门1 都达到人数目标,完成常规录取。

  • 补录:部门0 先选人,应聘者 4 和 5 与此前最后录取的应聘者1 的能力值相同,按规则补录一人(应聘者4)后结束招聘。 然后部门1 补录,没有人与此前最后录取的应聘者3 具备相同的能力值。

招聘结束后:部门0依次录取人员为 2 1 4,部门1依次录取人员为 3 (应聘者0 和 应聘者5 未被任何部门录取)

from typing import List
class DeptDemand:
    def __init__(self, dept_id, employ_num, progm_thd, tech_thd):
        self.dept_id = dept_id
        self.employ_num = employ_num
        self.progm_thd = progm_thd
        self.tech_thd = tech_thd
        # 记录录取人员
        self.employ_list = []
class Candidate:
    def __init__(self, candidate_id, progm_score, tech_score):
        self.candidate_id = candidate_id
        self.progm_score = progm_score  # 机考分数
        self.tech_score = tech_score  # 面试分数
class Solution:
    def __init__(self):
        self.finish = True
        self.temp = -1
    def recruitment_result(self, dept_demands: List[DeptDemand],
                           candidate_abilities: List[Candidate]) -> List[List[int]]:
        candidate_abilities.sort(key=lambda x: (x.tech_score, x.progm_score, -x.candidate_id), reverse=True)
        # 招聘池不再变化结束
        while len(candidate_abilities) != self.temp:
            self.temp = len(candidate_abilities)
            for dept_demand in dept_demands:
                if len(dept_demand.employ_list) < dept_demand.employ_num:  # 部门没招满
                    for num, candidate in enumerate(candidate_abilities):
                        if candidate.progm_score >= dept_demand.progm_thd and candidate.tech_score >= dept_demand.tech_thd:
                            dept_demand.employ_list.append(candidate_abilities.pop(num))
                            break
        # 补录环节
        for dept_demand in dept_demands:
            for num, candidate in enumerate(candidate_abilities):
                if dept_demand.employ_list:
                    last = dept_demand.employ_list[-1]
                    if candidate.progm_score == last.progm_score and candidate.tech_score == last.tech_score:
                        dept_demand.employ_list.append(candidate_abilities.pop(num))
                        break
                else:
                 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值