• 浇水


    浇水 (贪心 (star))

    • 在一条长 (n) 米,宽 (m) 米的长方形草地上放置着 (k) 个喷水装置。假设长方形草地的坐标范围为([0,0]sim[n,m]) ,那么第(i)个喷水装置的位置为 ((a_i,frac{m}{2})),也就是说喷水装置全部位于一条直线上。此外第 (i) 个喷水装置能向半径(r_i) 的圆形区域内喷水。
    • 负责管理喷水装置的园丁老大爷想知道,要想覆盖整个草地,至少需要开启多少个喷水装置。

    Input

    • 第一行三个正整数 (k, n)(m) 。其中 (m) 为偶数。
    • 接下来 (k) 行,每行两个整数 (a_i)(r_i),代表第 (i) 个喷水装置的横坐标和喷水半径。

    Output

    • 一个整数 (ans) 代表至少需要开启的喷水装置数量。若所有装置都开启依然不能覆盖整个草地则输出 (-1)

    Sample Input1

    9 16 6
    0 5
    2 5
    4 5
    6 5
    8 5
    10 5
    12 5
    14 5
    16 5
    

    Sample Output1

    2
    

    Sample Input2

    8 20 2
    5 3
    4 1
    1 2
    7 2
    10 2
    13 3
    16 2
    19 4
    

    Sample Output2

    6
    

    Hint

    • 样例 (1) 解释开启位于 (4)(12) 的喷水装置即可。
    • (30\%) 的数据中: (k ≤ 20)
    • 另有 (20\%) 的数据中: $r_i $ 均相等;
    • (100\%) 的数据中: (m ≤ 20000, r_i ≤ 10000,n, k ≤ 10^5, a_i ≤ n)

    分析

    • 喷水装置在长方形的中线上,如果某个喷水装置能喷到左上角的地方,那左下角必定能喷到。
    • 如果喷水装置的喷水半径小于 (frac{h}{2}) 此装置无用。
    • 所以我们可以预处理出每一个喷水装置能喷到的左、右最远的距离,然后对其左边界进行排序,从左到右,一次枚举花坛的未喷到的最远点,在能喷到的装置中找到右端点最远的装置。

    Code

    #include <bits/stdc++.h>
    const int maxn=1e5+5;
    int n,N,lenth,high;
    struct Node{
        double L,R;
    }a[maxn];
    bool cmp(const Node& a,const Node& b){
        return a.L < b.L;
    }
    void Read(){
        scanf("%d%d%d",&n,&lenth,&high);
        N = 0;
        for(int i = 1;i <= n;i++){
            int x,r;scanf("%d%d",&x,&r);
            if(r <= high/2)
                continue;
            a[++N].L = x - sqrt(r*r - high*high/4.0);
            a[N].R = x + sqrt(r*r - high*high/4.0);
        }
        std::sort(a+1,a+N+1,cmp);
    }
    void Solve(){
        double tail= 0;//记录已经浇到最右的距离
        int ans = 0,i = 1;
        while(tail < lenth){
            ans++;
            double s = tail;//记录未浇到的最右点
            for(;i<= N && a[i].L <= s;i++)
                if(tail < a[i].R)//能浇到s,就选尽量右的
                	tail=a[i].R;
            if(tail==s && s<lenth){//找不到能浇到s的点
                printf("-1
    ");
                return;
            }
        }
        printf("%d
    ",ans);
    }
    
    int main(){
        Read();
     	Solve();    
        return 0;
    }
    
  • 相关阅读:
    学习redis-安装和基本一些命令
    Eclipse启动报错Java was started but returned exit code=13
    踩过的坑系列之InputStream.read(byte[])方法
    <<深入Java虚拟机>>-虚拟机类加载机制-学习笔记
    <<深入Java虚拟机>>-第三章-垃圾收集器与内存分配策略-学习笔记
    <<深入Java虚拟机>>-第二章-Java内存区域-学习笔记
    创建线程的两种方式比较Thread VS Runnable
    Java设计模式之--代理模式学习
    shell脚本中$参数的介绍
    (转)使用DataTime这个类来获取当前的时间
  • 原文地址:https://www.cnblogs.com/hbhszxyb/p/13212743.html
Copyright © 2020-2023  润新知