喷水装置(二)

题目描述

  有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=100000)个点状的喷水装置,每个喷水装置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<bits/stdc++.h>
using namespace std;
struct node{
    double l,r;
}a[100005];
bool cmp(node x,node y){ return x.l<y.l; }
int N,n,w,h,num;
int main(){
    cin>>N;
    while(N--){//列  行
        cin>>n>>  w>>h;
        double H=h/2.0;
        int x,r;
        num=0;
        for(int i=1;i<=n;i++) {
            cin>>x>>r;
            if(r>H){
                double t=sqrt(r*r-H*H);
                a[++num].l=x-t;
                a[num].r=x+t;
            }
        }
        if(num==0){
            cout<<0<<"\n";
            continue;
        }
        sort(a+1,a+1+num,cmp);
        int cnt=0,flag=0;
        double pre=0;
        for(int i=1;i<=num;i++){
            if(pre>=w) break;
            int t=i,ma=a[i].r,ans=i;
            while(a[t].l<=pre&&t<=num){
                if(ma<a[t].r){
                    ma=a[t].r;
                    ans=t;
                }
                t++;
            }
            if(a[ans].l<=pre){
                cnt++;
                i=ans;
                pre=a[i].r;
            }
            else{
                cout<<0<<"\n";
                flag=1;
                break;
            }
        }
        if(!flag) cout<<cnt<<"\n";
    }
    return 0;
}
// 2147483647

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值