二分答案法

[Algo] 二分答案法

1. 机器人跳跃

// 1. 机器人跳跃
// https://www.nowcoder.com/practice/7037a3d57bbd4336856b8e16a9cafd71
bool complete(int energy, vector<int>& height, int max) {
    for (int i = 1; i < height.size(); i++) {
        if (height[i] > energy) energy -= height[i] - energy;
        else energy += energy - height[i];
        if (energy >= max) return true;
        if (energy < 0) return false;
    }
    return true;
}
int minEnergy(vector<int>& height) {
    int maxHeight = 0;
    for (int h : height) maxHeight = maxHeight >= h ? maxHeight : h;
    int l = 0, r = maxHeight, m, ans;
    while (l <= r) {
        m = (l + r) / 2;
        if (complete(m, height, maxHeight)) {
            ans = m;
            r = m - 1;
        } else l = m + 1;
    }
    return ans;
}

2. 找出第K小的数对距离

// 2. 找出第K小的数对距离
// https://leetcode.cn/problems/find-k-th-smallest-pair-distance/
int distanceNoMoreThan(vector<int>& nums, int k)
{
    int sum = 0;
    for (int l = 0, r = 0; l < nums.size(); l++)
    {
        while (r + 1 < nums.size() && nums[r + 1] - nums[l] <= k) r++;
        sum += r - l;
    }
    return sum;
}
int smallestDistancePair(vector<int>& nums, int k) {
    sort(nums.begin(), nums.end());
    int len = nums.size();
    int l = 0, r = nums[len - 1] - nums[0], m, ans;
    while (l <= r)
    {
        m = (l + r) / 2;
        if (distanceNoMoreThan(nums, m) < k) l = m + 1;
        else { ans = m; r = m - 1; }
    }
    return ans;
}

3. 计算等位时间

// 3. 计算等位时间
// 给定一个数组arr长度为n,表示n个服务员,每服务一个人的时间
// 给定一个正数m,表示有m个人等位,如果你是刚来的人,请问你需要等多久?
// 假设m远远大于n,比如n <= 10^3, m <= 10^9, 且遵循有空直接上的原则
struct Compare {
    bool operator()(const pair<int, int>& a, const pair<int, int>& b) {
        return a.first > b.first; // pair.first 越小优先级越高
    }
};
int waitingTime1(vector<int> &arr, int m)
{
    priority_queue<pair<int, int>, vector<pair<int, int>>, Compare> heap; 
    // pair.first - 空闲时刻, pair.second - 工作效率
    for (int i = 0; i < arr.size(); i++) heap.push(make_pair(0, arr[i]));
    for (int i = 0; i < m; i++)
    {
        pair<int, int> cur = heap.top();
        heap.pop();
        cur.first += cur.second;
        heap.push(cur);
    }
    return heap.top().first;
}

int f(vector<int> &arr, int time)
{
    int ans = 0;
    for (int num : arr) ans += time / num + 1;
    return ans;
}
int waitingTime2(vector<int> &arr, int m)
{
    int min_val = INT32_MAX;
    for (int num : arr) min_val = min(min_val, num);
    int l = 0, r = m * min_val, mid, ans;
    while (l <= r)
    {
        mid = (l + r) / 2;
        if (f(arr, mid) < m + 1) l = mid + 1;
        // f - 给定时间内能服务的客人总数(包括开始)
        else { ans = mid; r = mid - 1; }
    }
    return ans;
}
posted @ 2024-12-28 14:35  yaoguyuan  阅读(11)  评论(0)    收藏  举报