【题目描述】:喷水设置 有一块草坪,长为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处理 |