全部评论 1

  • #include <bits/stdc++.h>
    using namespace std;

    struct Sprinkler {
    double l, r;
    Sprinkler(double l = 0, double r = 0) : l(l), r(r) {}
    };

    int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int m;
    cin >> m;
    while (m--) {
        int n;
        double w, h;
        cin >> n >> w >> h;
    
        vector<Sprinkler> valid;
        double half_h = h / 2.0;
    
        for (int i = 0; i < n; i++) {
            double x, r;
            cin >> x >> r;
            if (r <= half_h) continue; // 无法到达上下边
            double d = sqrt(r * r - half_h * half_h);
            double l = x - d;
            double r_bound = x + d;
            // 截断到 [0, w] 范围内(只保留与草坪 x 轴重叠部分)
            l = max(0.0, l);
            r_bound = min(w, r_bound);
            if (l < r_bound) {
                valid.emplace_back(l, r_bound);
            }
        }
    
        // 按左端点升序,左端点相同时右端点降序(贪心需要)
        sort(valid.begin(), valid.end(), [](const Sprinkler& a, const Sprinkler& b) {
            if (a.l != b.l) return a.l < b.l;
            return a.r > b.r;
        });
    
        double cover = 0.0; // 当前覆盖到的最右位置
        int count = 0;
        int i = 0;
        int sz = valid.size();
    
        while (cover < w) {
            double max_r = cover;
            // 在所有左端点 <= cover 的区间中,找最大右端点
            while (i < sz && valid[i].l <= cover) {
                max_r = max(max_r, valid[i].r);
                i++;
            }
            // 如果没找到能延伸的区间,则断开
            if (max_r <= cover) {
                count = 0;
                break;
            }
            count++;
            cover = max_r;
            // 注意:这里不回退 i,因为已处理完所有 l <= old_cover 的区间
        }
    
        cout << count << '\n';
    }
    
    return 0;
    

    }

    1周前 来自 浙江

    0
暂无数据

提交答案之后,这里将显示提交结果~

首页