1 条题解

  • 0
    @ 2026-5-18 21:28:26

    解法思路

    1. 统计相同花瓣数的花朵数量

    首先将数组排序,然后统计每个花瓣数 xx 的出现次数,记作 cxc_x
    同时,因为总花费不能超过 mm,所以对于一种花瓣数 xx,最多只能选取 mx\left\lfloor \frac{m}{x} \right\rfloor 朵(否则总花瓣数会超过 mm),但实际数量受 cxc_x 限制,因此实际可选数量为 min(cx,m/x)\min(c_x, \lfloor m/x \rfloor)

    2. 枚举相邻花瓣数的组合

    由于任意两朵花的花瓣数之差不超过 11,所以选出的花束只可能包含两种相邻的花瓣数 xxx+1x+1(也可能只包含一种)。

    我们可以遍历所有可能的花瓣数 xx,并枚举选取 xx 的数量 k1k_10k1min(cx,m/x)0 \le k_1 \le \min(c_x, \lfloor m/x \rfloor))。
    此时已花费 k1xk_1 \cdot x 硬币,剩余硬币数为 mk1xm - k_1 \cdot x

    对于花瓣数 x+1x+1,最多可以选取

    $$k_2 = \min\left(c_{x+1},\ \left\lfloor \frac{m - k_1 \cdot x}{x+1} \right\rfloor\right) $$

    朵。

    则该组合的总花瓣数为 k1x+k2(x+1)k_1 \cdot x + k_2 \cdot (x+1)
    对所有 xx 和所有可能的 k1k_1 取最大值即可。

    3. 为什么枚举 k1k_1 的复杂度是 O(n)O(n)

    对于每个 xxk1k_100 枚举到 min(cx,m/x)\min(c_x, \lfloor m/x \rfloor)

    • 如果 m/xcx\lfloor m/x \rfloor \ge c_x,则枚举次数为 cx+1c_x+1
    • 如果 m/x<cx\lfloor m/x \rfloor < c_x,则枚举次数为 m/x+1\lfloor m/x \rfloor+1,此时因为 xx 很大,m/x\lfloor m/x \rfloor 很小,总和仍然受限于 nn 和不同 xx 的个数。

    事实上,所有 xxmin(cx,m/x)\min(c_x, \lfloor m/x \rfloor) 之和不超过 n+不同x的个数n + \text{不同}x\text{的个数},而不同 xx 的个数也 n\le n,因此总枚举次数为 O(n)O(n)

    排序的复杂度为 O(nlogn)O(n \log n),因此总复杂度为 O(nlogn)O(n \log n),满足题目要求(所有测试用例的 nn 之和不超过 2×1052 \times 10^5)。

    4. 边界处理

    • 当没有 x+1x+1 的花朵时,cx+1=0c_{x+1}=0,此时 k2=0k_2=0,相当于只选花瓣数为 xx 的花。
    • k1=0k_1=0 时,相当于只选花瓣数为 x+1x+1 的花。
    • 注意 mm 可能非常大(101810^{18}),但 xx 最小为 11,故 m/x\lfloor m/x \rfloor 在计算时需要用 64 位整数。

    算法步骤

    1. 读入 tt 组测试用例。
    2. 对每个测试用例:
      • 读入 n,mn, m 和数组 aa
      • aa 排序。
      • 统计每个不同花瓣数 xx 及其出现次数 cxc_x,存储到列表 pairs 中(例如 (x,cx)(x, c_x))。
      • 初始化答案 ans=0ans = 0
      • 遍历每个 xx(注意同时要能访问 cx+1c_{x+1},可以再存储一个映射或直接按顺序处理):
        • 设当前花瓣数为 xx,数量为 cxc_x;下一个花瓣数为 x=x+1x' = x+1,数量为 cxc_{x'}(若不存在则 cx=0c_{x'}=0)。
        • 计算 limit=min(cx,m/x)limit = \min(c_x, \lfloor m/x \rfloor)
        • 对于 k1=0k_1 = 0limitlimit
          • 剩余硬币 rem=mk1xrem = m - k_1 \cdot x
          • rem<0rem < 0 则跳出。
          • k2=min(cx, rem/(x+1))k_2 = \min(c_{x'},\ \lfloor rem / (x+1) \rfloor)
          • 更新 ans=max(ans, k1x+k2(x+1))ans = \max(ans,\ k_1 \cdot x + k_2 \cdot (x+1))
      • 输出 ansans

    示例验证

    以第一个测试用例为例:
    n=5,m=10n=5,m=10,花朵花瓣:[1,1,2,2,3][1,1,2,2,3]
    排序后得到:11 出现 22 次,22 出现 22 次,33 出现 11 次。

    • 枚举 x=1x=1c1=2c_1=210/1=10\lfloor 10/1 \rfloor=10limit=2limit=2

      • k1=0k_1=0rem=10rem=10k2=min(2,10/2=5)=2k_2=\min(2,\lfloor10/2\rfloor=5)=2,总花瓣 0+2×2=40+2\times2=4
      • k1=1k_1=1rem=9rem=9k2=min(2,9/2=4)=2k_2=\min(2,\lfloor9/2\rfloor=4)=2,总花瓣 1+4=51+4=5
      • k1=2k_1=2rem=8rem=8k2=min(2,8/2=4)=2k_2=\min(2,\lfloor8/2\rfloor=4)=2,总花瓣 2+4=62+4=6
    • 枚举 x=2x=2c2=2c_2=210/2=5\lfloor10/2\rfloor=5limit=2limit=2

      • k1=0k_1=0rem=10rem=10k2=min(1,10/3=3)=1k_2=\min(1,\lfloor10/3\rfloor=3)=1,总花瓣 0+3=30+3=3
      • k1=1k_1=1rem=8rem=8k2=min(1,8/3=2)=1k_2=\min(1,\lfloor8/3\rfloor=2)=1,总花瓣 2+3=52+3=5
      • k1=2k_1=2rem=6rem=6k2=min(1,6/3=2)=1k_2=\min(1,\lfloor6/3\rfloor=2)=1,总花瓣 4+3=74+3=7
    • 枚举 x=3x=3c3=1c_3=110/3=3\lfloor10/3\rfloor=3limit=1limit=1

      • k1=0k_1=0rem=10rem=10k2=0k_2=0(无 x+1=4x+1=4),总花瓣 00
      • k1=1k_1=1rem=7rem=7k2=0k_2=0,总花瓣 33

    最大值为 77,与样例输出一致。

    完整题解代码框架(C++ 风格)

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            vector<int> a(n);
            bool hasZero = false;
            int negCount = 0;
            for (int i = 0; i < n; i++) {
                cin >> a[i];
                if (a[i] == 0) hasZero = true;
                else if (a[i] < 0) negCount++;
            }
            // 乘积为负:奇数个负数且无0
            if (!hasZero && negCount % 2 == 1) {
                cout << "0\n";
            } 
            // 乘积为0
            else if (hasZero) {
                cout << "0\n";
            } 
            // 乘积为正
            else {
                cout << "1\n";
                // 输出任意一个元素改成0
                cout << "1 0\n";
            }
        }
        return 0;
    }
    

    复杂度分析

    • 排序:O(nlogn)O(n \log n)
    • 统计和枚举:O(n)O(n)(因为每个花朵最多被作为 k1k_1 枚举一次)
    • 总复杂度:O(nlogn)O(n \log n),满足题目限制。
    • 1

    信息

    ID
    7234
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    1
    已通过
    1
    上传者