【贪心问题】喷水装置

喷水装置

链接:vjudge 喷水装置

题目描述

长 L 米,宽 W 米的草坪里装有 n 个浇灌喷头。每个喷头都装在草坪中心线上(离两边各 W/2米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。
请问:如果要同时浇灌整块草坪,最少需要打开多少个喷头?

在这里插入图片描述

输入格式

输入包含若干组测试数据。
第一行一个整数 T 表示数据组数;
每组数据的第一行是整数 n、L 和 W;
接下来的 n 行,每行包含两个整数,给出一个喷头的位置和浇灌半径(上面的示意图是样例输入第一组数据所描述的情况)。

输出格式

对每组测试数据输出一个数字,表示要浇灌整块草坪所需喷头数目的最小值。如果所有喷头都打开也不能浇灌整块草坪,则输出 -1 。

思路

  1. 题目中喷水装置是一个圆形的范围,为了方便处理可以将它看成一个矩形,左右端点则为圆形与草坪的交点。若两个圆形重合只需判断两个矩形的左端点和右端点大小关系。
  2. 采取一个贪心的策略,每次都找到一个左端点<=草坪左侧,右端点最大的矩形,如果能找到则将草坪左端点更新矩形的右端点,继续重复这个操作。如果没找到符合的矩形,那么说明无法灌溉整块草坪。
  3. 为了提高效率,可以在搜索时候判断,将不符合条件的点提前去除(半径小于W/2、右端点<0、左端点>L)。

代码

#include<bits/stdc++.h>
using namespace std;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

typedef long long ll;
typedef pair<double, double> PDD;

int t, n, idx, ans;
double sta, maxr;
double l, w, p, r;
vector<PDD> vpd;
 
int main() {
    io_opt;
    cin >> t;
    while (t--) {
        cin >> n >> l >> w;
        w /= 2;
        sta = 0, ans = 0;
        vpd.clear();
        while (n--) {
            cin >> p >> r;
            if (r <= w) continue;
            double tt = sqrt(pow(r, 2) - pow(w, 2));
            if (p - tt > l || p + tt < 0) continue;
            vpd.push_back({ p - tt,p + tt });
        }
        sort(vpd.begin(), vpd.end());
        while (sta < l && !vpd.empty()) {
            idx = -1, maxr = 0;
            for (int i = 0; i < vpd.size(); i++) {
                if (vpd[i].first <= sta && vpd[i].second > maxr){
                    maxr = vpd[i].second;
                    idx = i;
                }
            }
            if (idx == -1) break;
            ans++;
            sta = maxr;
            vpd.erase(vpd.begin() + idx);
        }
        if (sta < l) cout << -1 << endl;
        else cout << ans << endl;
    }
    return 0;
}```

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值