• UVA 10382喷水设施


    UVA 10382

    【题目描述】:喷水设置

    有一块草坪,长为l,宽为w,在草坪的中心线上,放置规格不一的喷水装置,给定每个装置的安置中心,辐射半径(pos,rad)。求最少几个喷水装置可以辐射整块草坪?

    【算法分析】:

    把二维退化到一维问题,我们要考虑的辐射边界,pos+(-)sqrt(rad^2-w^2/4),想象一下,如果边界辐射到了,中间一定辐射到了,若rad<w/2的话,是不起作用的,要丢弃。

    现在的模型,给定多条线段的,坐标表示(l,r),现在要让这个线段覆盖[0,l]这段范围。用贪心策略,设置当前覆盖的位置np,每次选择一条左端点在np的左边(或包括),右端面最靠右的,贪心模拟即可。为了减少每次选择的复杂度,预先排序即可。

    【注意】:但是最坑的是eps啊,一定要注意做差和大小写符号。不然一直W。= =

    //深坑,这道题的坑不在于算法,而是eps的处理啊,超时和W的血泪史,eps写不好不仅会W

    //更坑的是超时啊

    【完整代码】:

      1 #include<iostream>
      2 
      3 #include<stdio.h>
      4 
      5 #include<string.h>
      6 
      7 #include<algorithm>
      8 
      9 #include<stdlib.h>
     10 
     11 #include<math.h>
     12 
     13 #include<queue>
     14 
     15 #include<vector>
     16 
     17 #include<map>
     18 
     19 #define MAXN 10000+5
     20 
     21 #define MAXM 50+5
     22 
     23 #define oo 95565354451
     24 
     25 #define eps 0.000001
     26 
     27 #define PI acos(-1.0)//这个精确度高一些
     28 
     29 #define REP1(i,n) for(int i=0;i<(n);i++)
     30 
     31 #define REP2(i,n) for(int i=1;i<=(n);i++)
     32 
     33 using namespace std;
     34 
     35  
     36 
     37 int n;
     38 
     39 double l,w;
     40 
     41 int cnt;
     42 
     43 struct Line
     44 
     45 {
     46 
     47     double x;
     48 
     49     double y;
     50 
     51     bool operator <(const Line& l) const
     52 
     53     {
     54 
     55         return x<l.x;
     56 
     57     }
     58 
     59 } line[MAXN];
     60 
     61  
     62 
     63 void RandB()
     64 
     65 {
     66 
     67     cnt=0;
     68 
     69     for(int i=0; i<n; i++)
     70 
     71     {
     72 
     73         double pos,rad;
     74 
     75         scanf("%lf%lf",&pos,&rad);
     76 
     77         if (rad<w/2) continue;
     78 
     79         double sq=sqrt(rad*rad-(w*w)/4);
     80 
     81         double x=pos-sq,y=pos+sq;
     82 
     83         if (x>=l || y<=0) continue;
     84 
     85         line[cnt].x=pos-sq;
     86 
     87         line[cnt++].y=pos+sq;
     88 
     89     }
     90 
     91     sort(line,line+cnt);
     92 
     93 }
     94 
     95 int solve()
     96 
     97 {
     98 
     99     double Npos=0;//当前坐标
    100 
    101     int p=0;//指针,指向line
    102 
    103     int ans=0;
    104 
    105     if (line[0].x>eps || cnt==0) return -1;
    106 
    107     else
    108 
    109     {
    110 
    111         while(l-Npos>eps && p<cnt)
    112 
    113         {
    114 
    115             if (line[p].x-Npos>=eps) break;
    116 
    117             double most=Npos;//找到最远的y
    118 
    119             while(line[p].x-Npos<=eps && p<cnt)
    120 
    121             {
    122 
    123                 most=max(most,line[p].y);    //x在Npos的左边,贪心去y最大的
    124 
    125                 p++;
    126 
    127             }
    128 
    129             ans++;
    130 
    131             Npos=most;
    132 
    133         }
    134 
    135     }
    136 
    137     if (l-Npos>=eps) return -1;
    138 
    139     else  return ans;
    140 
    141 }
    142 
    143 int main()
    144 
    145 {
    146 
    147     while(~scanf("%d%lf%lf",&n,&l,&w))
    148 
    149     {
    150 
    151         RandB();
    152 
    153         printf("%d
    ",solve());
    154 
    155     }
    156 
    157     return 0;
    158 
    159 }

     

     【关键词】:降维,eps处理
  • 相关阅读:
    Android 开发笔记___复选框__checkbox
    Android 开发笔记___FrameLayout
    Android 开发笔记___RelativeLayout
    Android 开发笔记___初级控件之实战__计算器
    Android 开发笔记___shape
    Android 开发笔记___DateUtil——Time
    改良版 导航栏自动跟随
    简洁 js排序算法
    简单使用rem方案适配移动设备
    导航栏监听页面滚动跟随 简单封装
  • 原文地址:https://www.cnblogs.com/little-w/p/3525281.html
Copyright © 2020-2023  润新知