首页 > 代码库 > 喷水装置2 贪心

喷水装置2 贪心

喷水装置(二)

时间限制:3000 ms  |  内存限制:65535 KB
难度:4
 
描述
有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
 
输入
第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
输出
每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。
样例输入
2
2 8 6
1 1
4 5
2 10 6
4 5
6 5
样例输出
1
2

#include<iostream>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN  10003
#define INF 1000000009
/*
    喷水装置2
    在给定装置(位置X确定)中选尽量少的
    可以得出贡献长方形的长度,转化为线段
    在一堆线段中选择尽量少的覆盖所有:
        按起点排序,遍历一遍即可
*/
int T;
double n, w, h, E, r[MAXN], x[MAXN];
struct node
{
    double beg, end;
};
vector<node> v;
bool cmp(node a, node b)
{
    return a.beg < b.beg;
}
int main()
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        cin >> n >> w >> h;
        node tmp;
        v.clear();
        E = 0.0;
        for (int i = 0; i < n; i++)
        {
            cin >> x[i] >> r[i];
            if (r[i] * r[i] - (h / 2)*(h / 2) > 0)
            {
                tmp.beg = x[i] - sqrt(r[i] * r[i] - (h / 2)*(h / 2));
                //tmp.beg = max(0.0, tmp.beg);
                tmp.end = x[i] + sqrt(r[i] * r[i] - (h / 2)*(h / 2));
                //tmp.end = min(w, tmp.end);
                v.push_back(tmp);
            }
        }
        sort(v.begin(), v.end(),cmp);
        int i = 0,cnt = 0;
        while(E<w)
        {
            double m = 0.0;
            for (i = 0; i < v.size() && v[i].beg <= E; i++)
            {
                m = max(m, v[i].end - E);
            }
            if (m!=0)
            {
                cnt++;
                E += m;
            }
            else
                break;
        }
        if (E < w)
            cout << 0 << endl;
        else
            cout << cnt << endl;
    }
}

 

喷水装置2 贪心