1、UVa 10382 - Watering Grass (贪心—区间覆盖)
题意:一块矩形草坪,给出若干个分布在中轴线上的喷水装置,喷水范围为圆形。问能否覆盖整个草坪,若能,求出最少的喷水装置数目。
思路:圆形半径小于等于草坪宽度一半的不用考虑;在剩下的喷水圆形区域中,求出对应覆盖草坪的矩形区块,之后则进行贪心处理:找出矩形区块[L,R]左侧L小于等于当前已覆盖区域的右侧POS的区块中,右侧R最大的那个,同时更新POS.
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 struct sprk 6 { 7 double r,ldis; 8 double L, R; 9 }v[10005]; 10 double n, l, w; 11 bool Cmp(const sprk& a, const sprk& b) 12 { 13 if (a.L < b.L) return true; 14 else if (a.L == b.L) 15 { 16 if (a.R < b.R) return true; 17 else return false; 18 } 19 else return false; 20 } 21 int main() 22 { 23 while (cin >> n >> l >> w) 24 { 25 int sz = 0; 26 sprk tmp; 27 for (int i = 0; i < n; i++) 28 { 29 cin >> tmp.ldis >> tmp.r; 30 if (tmp.r <=w/2.0) continue; 31 double tl = sqrt(tmp.r*tmp.r-w*w/4.0); 32 tmp.L = tmp.ldis*1.0 - tl; 33 tmp.R = tmp.ldis*1.0 + tl; 34 if (tmp.R < 0) continue; 35 v[sz++] = tmp; 36 } 37 sort(v, v+sz, Cmp); 38 int num = 0; 39 double pos = 0; 40 int k = 0; 41 bool ok = false; 42 if (sz>0&&v[0].L <= 0) 43 { 44 k = 0; 45 pos = 0; 46 while (k < sz) 47 { 48 int j = k; 49 double Rpos = pos; 50 while (j < sz&&v[j].L <= pos) 51 { 52 if (v[j].R > Rpos) Rpos = v[j].R; 53 ++j; 54 } 55 if (j == k)break; 56 num++; 57 pos = Rpos; 58 k = j; 59 if (pos >= l) 60 { 61 ok = true; 62 break; 63 } 64 } 65 } 66 if(ok) cout << num << endl; 67 else cout << -1 << endl; 68 } 69 return 0; 70 }