【2024华为OD-E卷-100分-用户调度问题】(题目+思路+Java&C++&Python解析)

题目描述

用户调度问题

给定一个用户列表,每个用户有一个开始时间和结束时间,代表该用户希望使用系统的时间段。系统每次只能为一个用户提供服务。现在需要设计一个调度算法,使得尽可能多的用户得到满足(即在他们的希望时间段内获得系统服务)。

输入

  • 第一行是一个整数 n,表示用户数量。
  • 接下来 n 行,每行两个整数 start 和 end,表示一个用户的希望时间段 [start, end)。

输出

  • 输出一个整数,表示最多能满足的用户数量。

示例输入

4
1 4
2 5
3 6
0 7

示例输出

3

思路

这个问题可以看作是一个区间调度问题,可以使用贪心算法来解决。贪心算法的基本思路是:

  1. 将所有用户的时间段按结束时间从小到大排序。
  2. 从第一个时间段开始,依次选择不冲突的时间段(即当前时间段的开始时间大于或等于上一个被选择时间段的结束时间)。

通过这种方法,可以确保选择的时间段数量最多,因为每次选择的都是结束时间最早且不与之前选择的时间段冲突的时间段。

Java 编码解析

import java.util.*;

class User {
    int start;
    int end;

    User(int start, int end) {
        this.start = start;
        this.end = end;
    }
}

public class UserScheduling {
    public static int maxUsers(int n, int[][] intervals) {
        List<User> users = new ArrayList<>();
        for (int[] interval : intervals) {
            users.add(new User(interval[0], interval[1]));
        }
        // 按结束时间排序
        users.sort(Comparator.comparingInt(a -> a.end));

        int count = 0;
        int lastEnd = -1; // 上一个被选择的时间段的结束时间

        for (User user : users) {
            if (user.start >= lastEnd) {
                count++;
                lastEnd = user.end;
            }
        }

        return count;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[][] intervals = new int[n][2];
        for (int i = 0; i < n; i++) {
            intervals[i][0] = scanner.nextInt();
            intervals[i][1] = scanner.nextInt();
        }
        System.out.println(maxUsers(n, intervals));
        scanner.close();
    }
}

C++ 编码解析

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct User {
    int start;
    int end;
    bool operator<(const User& other) const {
        return end < other.end;
    }
};

int maxUsers(int n, const vector<pair<int, int>>& intervals) {
    vector<User> users;
    for (const auto& interval : intervals) {
        users.emplace_back(interval.first, interval.second);
    }
    // 按结束时间排序
    sort(users.begin(), users.end());

    int count = 0;
    int lastEnd = -1; // 上一个被选择的时间段的结束时间

    for (const auto& user : users) {
        if (user.start >= lastEnd) {
            count++;
            lastEnd = user.end;
        }
    }

    return count;
}

int main() {
    int n;
    cin >> n;
    vector<pair<int, int>> intervals(n);
    for (int i = 0; i < n; ++i) {
        cin >> intervals[i].first >> intervals[i].second;
    }
    cout << maxUsers(n, intervals) << endl;
    return 0;
}

Python 编码解析

def max_users(n, intervals):
    # 按结束时间排序
    intervals.sort(key=lambda x: x[1])

    count = 0
    last_end = -1  # 上一个被选择的时间段的结束时间

    for start, end in intervals:
        if start >= last_end:
            count += 1
            last_end = end

    return count

if __name__ == "__main__":
    n = int(input().strip())
    intervals = []
    for _ in range(n):
        start, end = map(int, input().strip().split())
        intervals.append((start, end))
    print(max_users(n, intervals))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执着的小火车

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值