• 南阳OJ-12-喷水装置(二)贪心+区间覆盖


    题目链接:

    http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=12

    题目大意:

    有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。

    传送门:喷水装置(一)

    思路:

    区间覆盖问题,每个点有一段喷水区间,按照左端点排序即可,设置两变量begin, end,依次扫过去,每次取覆盖begin的区间更新end,如果没能覆盖begin,说明已经到了当前的最右端,begin=end,再次扫描,如果每次扫描开始的时候就不能覆盖begin,则无解,如果每次扫描的时候没有找到合适的end,也无解。如果最终的begin<l也表示到达不了终点。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn = 1e4 + 10;
     8 int T, n;double l, w;
     9 struct node
    10 {
    11     double x, y;
    12     bool operator < (const node a)const
    13     {
    14         return x < a.x;
    15     }
    16     node(){}
    17     node(double x, double y):x(x), y(y){}
    18 };
    19 node a[maxn];
    20 int main()
    21 {
    22     cin >> T;
    23     while(T--)
    24     {
    25         cin >> n >> l >> w;
    26         w = w * 0.5;
    27         int tot = 0;
    28         double x, r;
    29         for(int i = 0; i < n; i++)
    30         {
    31             cin >> x >> r;
    32             if(r <= w)continue;
    33             double c = sqrt(1.0 * r * r - w * w);
    34             a[tot].x = 1.0 * x - c;
    35             a[tot++].y = 1.0 * x + c;
    36             if(a[tot - 1].x > l || a[tot - 1].y < 0)tot--;
    37         }
    38         sort(a, a + tot);
    39         double begin = 0, end = -1;
    40         int ans = 0;
    41         for(int i = 0; i < tot && begin < l;)
    42         {
    43             if(a[i].x > begin)
    44             {
    45                 ans = 0;
    46                 break;
    47             }
    48             while(i < tot && a[i].x <= begin)//覆盖begin的区间更新出最大的end
    49             {
    50                 end = max(end, a[i].y);
    51                 i++;
    52             }
    53             if(end < 0)//说明没有找到合适的区间,直接无解
    54             {
    55                 ans = 0;
    56                 break;
    57             }
    58             ans++;
    59             begin = end;//更新两者
    60             end = -1;
    61         }
    62         if(begin < l)ans = 0;
    63         cout<<ans<<endl;
    64     }
    65     return 0;
    66 }
  • 相关阅读:
    select详解
    java Map及Map.Entry详解
    Java 基本类型
    java 获取String出现最多次数的字段
    java 居民身份证的校验
    java 删除文件
    Java 导出excel进行换行
    获取文件及其文件路径
    List<Map<String,Object>> 中文排序
    Java ----单个list 删除元素
  • 原文地址:https://www.cnblogs.com/fzl194/p/8683980.html
Copyright © 2020-2023  润新知