考察知识点:二分
不难看出每种礼包的构成:「1 个 U 盘 + 1 个鼠标」 + 1 个「U 盘 / 鼠标 / 键盘」 设 U 盘、鼠标、键盘数量为 ,分配完每个礼包本身含有的 1 个 U 盘和 1 个鼠标后的 U 盘、鼠标数量为 ,礼包数量为 ,则有以下关系式:
由于相邻两位大佬的礼包不能相同,所以还需要满足:
U 盘 / 鼠标 / 键盘中最少的两种物品不少于礼包总数的一半
基于以上判断条件,使用二分查找 范围内满足条件的最大礼包数量即可。
时间复杂度:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
bool check(int a, int b, int c, int m)  // a: U盘数量,b: 鼠标数量,c: 键盘数量,m: 礼包数量
{
    a -= m;
    b -= m;
    if (a < 0 || b < 0 || c < 0 || a + b + c < m)
        return false;
    int t[3] = {a, b, c};
    sort(t, t + 3);
    return t[0] + t[1] >= m / 2;        // 相邻的两位礼包不同,要求最少的两种礼包数量之和大于等于礼包总数量的一半
}
void solve()
{
    int a, b, c;
    cin >> a >> b >> c;
    int l = 0, r = a + b + c;
    while (l < r)                       // 二分查找礼包数量
    {
        int m = (l + r + 1) >> 1;
        if (check(a, b, c, m))
            l = m;
        else
            r = m - 1;
    }
    cout << l << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

京公网安备 11010502036488号