长 L米,宽 W 米的草坪里装有 n个浇灌喷头。每个喷头都装在草坪中心线上(离两边各 W2 米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。
请问:如果要同时浇灌整块草坪,最少需要打开多少个喷头?
输入
输入包含若干组测试数据。
第一行一个整数 T 表示数据组数;
每组数据的第一行是整数 n、L 和 W;
接下来的 n 行,每行包含两个整数,给出一个喷头的位置和浇灌半径(上面的示意图是样例输入第一组数据所描述的情况)。
对于 100% 的数据,n≤15000。
输出
对每组测试数据输出一个数字,表示要浇灌整块草坪所需喷头数目的最小值。如果所有喷头都打开也不能浇灌整块草坪,则输出−1。
样例输入
样例输出
解题思路: 贪心思想 选能够覆盖该点的最右边的线段,然后更新覆盖点使覆盖点变为该线段的最右边的饿位置
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int t,num; 5 int n,L,W; 6 const int N=15005; 7 8 struct Node{ 9 double x,y; 10 bool operator<(const Node&X) const{ 11 return x<X.x; 12 } 13 }A[N]; 14 15 void cultilate(){ 16 sort(A+1,A+1+num); 17 double weizhi=0.0; 18 int res=0,ans=1,vis=1; 19 while(weizhi<L){ 20 res++; 21 double temp=weizhi; 22 while(temp>=A[ans].x&&ans<=num){ 23 if(A[ans].y>weizhi) weizhi=A[ans].y; 24 ans++; 25 } ///找能够覆盖该点的最右边的位置 26 // cout << ans << " " << num << endl; 27 // cout << weizhi << endl; 28 // cout << res << endl; 29 if(ans>num) break; 30 if(temp==weizhi) {vis=0;break;} 31 } 32 if(weizhi<L) vis=0; 33 if(vis) cout << res << endl; 34 else cout << -1 << endl; 35 } 36 37 int main() 38 { 39 ios::sync_with_stdio(false); 40 cin>>t; 41 while(t--){ 42 cin>>n>>L>>W; 43 num=0; 44 for(int i=1,d1,d2;i<=n;i++){ 45 cin>>d1>>d2; 46 if(2*d2<=W) continue; 47 else{ 48 double w1=d1-sqrt(d2*d2-W*W/4.0); 49 double w2=d1+sqrt(d2*d2-W*W/4.0); 50 A[++num]={w1,w2}; 51 } 52 } 53 cultilate(); 54 } 55 return 0; 56 }