1 条题解

  • 0
    @ 2026-5-19 19:55:16

    D. Place of the Olympiad 详细题解

    一、问题重述

    有一个 n×mn \times m 的矩形场地,要放置 kk 个桌位。桌位只能放在格子里,同一行中连续放置的桌位形成一条长凳。要求最小化最长长凳的长度

    例如,n=3,m=4,k=7n=3, m=4, k=7 时,最优安排是每行最多连续 22 个桌位,答案为 22


    二、核心思路

    2.1 函数定义

    设最长长凳长度为 xx。在一行中,如何安排才能容纳最多的桌位?

    • 将每 x+1x+1 个位置视为一个:前 xx 个位置放桌位(形成一个长凳),第 x+1x+1 个位置空出作为分隔。
    • 每行可以放 mx+1\left\lfloor \frac{m}{x+1} \right\rfloor 个完整的块,产生 mx+1x\left\lfloor \frac{m}{x+1} \right\rfloor \cdot x 个桌位。
    • 最后剩余 mmod(x+1)m \bmod (x+1) 个位置,可以再放 min(mmod(x+1),x)\min(m \bmod (x+1), x) 个桌位(若余数小于等于 xx 则全放,否则不能超过 xx,但余数肯定小于 x+1x+1,所以当余数为 xx 时也可以放 xx 个)。

    因此一行最多容纳的桌位数为:

    $$f(x) = x \cdot \left\lfloor \frac{m}{x+1} \right\rfloor + \min\left(m \bmod (x+1),\; x\right) $$

    实际余数部分就是 mmod(x+1)m \bmod (x+1),因为余数 <x+1< x+1,且当余数等于 xx 时也可以放 xx 个。所以:

    $$f(x) = x \cdot \left\lfloor \frac{m}{x+1} \right\rfloor + \left(m \bmod (x+1)\right) $$

    2.2 可行性条件

    由于 nn 行独立,总共最多可以放 nf(x)n \cdot f(x) 个桌位。要能容纳 kk 个桌位,需满足:

    nf(x)kn \cdot f(x) \ge k

    2.3 单调性

    xx 增大时,f(x)f(x) 也单调非减(允许更长的长凳,可以放更多桌位)。因此可以用二分查找最小的 xx 满足 nf(x)kn \cdot f(x) \ge k


    三、公式推导(可选)

    对于给定 xx,$f(x) = \left\lceil \frac{m}{x+1} \cdot x \right\rceil$ 的近似?不精确。更简单的:一行中最少需要的空位数kn\left\lceil \frac{k}{n} \right\rceil 个桌位时,用二分找 xx

    但标程使用二分查找,简洁有效。


    四、标程代码

    #include <iostream>
    using namespace std;
    
    void solve() {
        long long n, m, k;
        cin >> n >> m >> k;
        
        long long l = 0, r = m;  // 答案在 [1, m] 之间
        while (l + 1 < r) {
            long long mid = (l + r) / 2;
            // 计算当最大 bench 长度为 mid 时,一行最多能放多少个座位
            long long seats_per_row = (m / (mid + 1)) * mid + (m % (mid + 1));
            if (seats_per_row * n >= k) {
                r = mid;  // 可行,尝试更小的长度
            } else {
                l = mid;
            }
        }
        cout << r << endl;
    }
    
    int main() {
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
        return 0;
    }
    

    五、示例验证

    示例 1:n=3,m=4,k=7n=3, m=4, k=7

    • 二分:
      • mid=2mid=2:每块长度 332+12+1),4/3=1\lfloor 4/3 \rfloor=1 块 → 1×2=21 \times 2 = 2,余数 4%3=14\%3=1 → 可加 11,共 33 个/行,3×3=973 \times 3 = 9 \ge 7 ✅ → r=2r=2
      • mid=1mid=1:每块长度 224/2=2\lfloor 4/2 \rfloor=2 块 → 2×1=22 \times 1 = 2,余数 00,共 22 个/行,3×2=6<73 \times 2 = 6 < 7 ❌ → 最终 r=2r=2

    示例 2:n=5,m=5,k=5n=5, m=5, k=5

    • mid=1mid=1:每块长度 225/2=2\lfloor 5/2 \rfloor=2 块 → 2×1=22 \times 1=2,余数 11 → 共 33 个/行,5×3=1555\times 3=15\ge5 ✅ → 继续缩小
    • mid=0mid=0:每块长度 115/1=5\lfloor 5/1 \rfloor=5 块 → 5×0=05\times0=0,余数 00,共 00 个/行 ❌ → 答案为 11

    示例 3:n=1,m=13,k=2n=1, m=13, k=2

    • 最长 bench 长度为 11 时,一行最多放 $\lfloor 13/2 \rfloor \times 1 + (13\%2)=6+1=7 \ge 2$ ✅ → 答案为 11

    六、复杂度分析

    • 二分查找:O(logm)O(\log m)
    • 总复杂度:O(tlogm)O(t \log m)t104t \le 10^4m109m \le 10^9,完全可行

    七、总结

    步骤 操作
    1 二分答案 xx(最长 bench 长度)
    2 计算当 bench 长度为 xx 时,一行最多能放的座位数 f(x)f(x)
    3 nf(x)kn \cdot f(x) \ge k,则 xx 可行,缩小右边界
    4 否则增大左边界

    核心公式

    $$f(x) = x \cdot \left\lfloor \frac{m}{x+1} \right\rfloor + \left(m \bmod (x+1)\right) $$

    利用二分查找最小 xx 满足 nf(x)kn \cdot f(x) \ge k

    • 1

    信息

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