(B卷,200分)- 最少面试官数(Java & JS & Python)

题目描述

某公司组织一场公开招聘活动,假设由于人数和场地的限制,每人每次面试的时长不等,并已经安排给定,用(S1,E1)、 (S2,E2)、 (Sj,Ej)…(Si < Ei,均为非负整数)表示每场面试的开始和结束时间。

面试采用一对一的方式,即一名面试官同时只能面试一名应试者,一名面试官完成一次面试后可以立即进行下一场面试,且每个面试官的面试人次不超过 m。

为了支撑招聘活动高效顺利进行,请你计算至少需要多少名面试官。

输入描述

输入的第一行为面试官的最多面试人次 m,第二行为当天总的面试场次 n,

接下来的 n 行为每场面试的起始时间和结束时间,起始时间和结束时间用空格分隔。

其中, 1 <= n, m <= 500

输出描述

输出一个整数,表示至少需要的面试官数量。

用例

输入 2
5
1 2
2 3
3 4
4 5
5 6
输出 3
说明 总共有 5 场面试,且面试时间都不重叠,但每个面试官最多只能面试 2 人次,所以需要 3 名面试官。
输入 3
3
1 2
2 3
3 4
输出 1
说明 总共有3场面试,面试时间不重叠,每个面试官最多能面试3人次,所以只需要一名面试官
输入 3
3
8 35
5 10
1 3
输出 2
说明 总共有3场面试,[5,10]和[8,35]有重叠,所以至少需要2名面试官

 

题目解析

本题要想面试官人数最少,则需要每个面试官面试尽量多的人。

我们将每个面试官想象成一个桶,每个面试者想象成一个球。

首先,我们需要对面试者的面试时间段,按照结束时间进行升序。

求解最大不相交区间数,需要将区间按结束位置升序:

由于不知道面试官个数,因此初始化时,有几个面试者就预定几个面试官,比如用例中有5个面试者,那就是初始化预定5个面试官。

接着,就是球放桶的问题了。

第一个球,放第一个桶。

第二个球,先尝试放第一个桶,首先检查桶中球个数是否已达到m,若已达到,则不能放入,继续尝试放入下一个桶,若未达到,则将球和桶最上面的球比较,即看面试时间是否有交集,如果有交集,则不能放入,继续尝试放入下一个桶,如果没有交集,则可以放入。

按照上面逻辑,放入所有球。

然后把空桶排除掉,剩下还有几个桶,就需要几个面试官。

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
let m, n;
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 2) {
    m = lines[0] - 0;
    n = lines[1] - 0;
  }

  if (n && lines.length === n + 2) {
    const ranges = lines.slice(2).map((line) => line.split(" ").map(Number));
    console.log(getResult(ranges, m, n));
    lines.length = 0;
  }
});

function getResult(ranges, m, n) {
  // 求解最大不相交区间时,需要将所有区间按照右边界升序
  ranges.sort((a, b) => a[1] - b[1]);
  const buckets = new Array(n).fill(0).map(() => new Array());

  for (let [s, e] of ranges) {
    for (let bucket of buckets) {
      // 每个面试官最多面试m次
      if (bucket.length < m && (bucket.length == 0 || bucket.at(-1) <= s)) {
        bucket.push(e);
        break;
      }
    }
  }

  return buckets.filter((bucket) => bucket.length > 0).length;
}

Java算法源码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;

public class Main {
  // 输入获取
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int m = sc.nextInt();
    int n = sc.nextInt();

    int[][] ranges = new int[n][2];
    for (int i = 0; i < n; i++) {
      ranges[i][0] = sc.nextInt();
      ranges[i][1] = sc.nextInt();
    }

    System.out.println(getResult(m, n, ranges));
  }

  // 算法入口
  public static long getResult(int m, int n, int[][] ranges) {
    // 求解最大不相交区间时,需要将所有区间按照右边界升序
    Arrays.sort(ranges, (a, b) -> a[1] - b[1]);

    ArrayList<LinkedList<Integer>> buckets = new ArrayList<>();
    for (int i = 0; i < n; i++) buckets.add(new LinkedList<>());

    for (int[] range : ranges) {
      int s = range[0];
      int e = range[1];

      for (LinkedList<Integer> bucket : buckets) {
        // 每个面试官最多面试m次
        if (bucket.size() < m && (bucket.size() == 0 || bucket.getLast() <= s)) {
          bucket.add(e);
          break;
        }
      }
    }

    return buckets.stream().filter(bucket -> bucket.size() > 0).count();
  }
}

Python算法源码

# 输入获取
m = int(input())
n = int(input())
areas = [list(map(int, input().split())) for _ in range(n)]


# 算法入口
def getResult():
    # 求解最大不相交区间时,需要将所有区间按照右边界升序
    areas.sort(key=lambda x: x[1])

    buckets = [[] for _ in range(n)]

    for s, e in areas:
        for bucket in buckets:
            # 每个面试官最多面试m次
            if len(bucket) < m and (len(bucket) == 0 or bucket[-1] <= s):
                bucket.append(e)
                break

    return len(list(filter(lambda b: len(b) > 0, buckets)))


# 算法调用
print(getResult())

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?