poj_1328_Radar Installation(区间贪心)
2013-09-24 23:24
621 查看
題型:貪心
題意:
有n個點在海里,現在需要用雷達將這些店覆蓋,雷達的輻射範圍是半徑為d的圓,設海岸綫為x軸,雷達要建在x軸上,問最少要多少個雷達能將這些點全部覆蓋。
分析:
既然雷達具有輻射半徑,那麽對於點(x,y),如果y>d,那麽就不可能被覆蓋到,則輸出-1;如果y<=d,那麽雷達安裝的範圍必須在[x-sqrt(d^2-y^2),x+sqrt(d^2-y^2)]區間内。
首先求出每個點所要求的區間,然後按集合右邊界大小進行排序,然後從左邊的集合的右邊界開始找,若該邊界所處集合所屬的點沒有被覆蓋,那麽在這個集合的右邊界檢建一個雷達,然後將集合左邊界處於該雷達左邊的集合刪除,最後貪心下去即可得到答案。
代碼:
題意:
有n個點在海里,現在需要用雷達將這些店覆蓋,雷達的輻射範圍是半徑為d的圓,設海岸綫為x軸,雷達要建在x軸上,問最少要多少個雷達能將這些點全部覆蓋。
分析:
既然雷達具有輻射半徑,那麽對於點(x,y),如果y>d,那麽就不可能被覆蓋到,則輸出-1;如果y<=d,那麽雷達安裝的範圍必須在[x-sqrt(d^2-y^2),x+sqrt(d^2-y^2)]區間内。
首先求出每個點所要求的區間,然後按集合右邊界大小進行排序,然後從左邊的集合的右邊界開始找,若該邊界所處集合所屬的點沒有被覆蓋,那麽在這個集合的右邊界檢建一個雷達,然後將集合左邊界處於該雷達左邊的集合刪除,最後貪心下去即可得到答案。
代碼:
#include<iostream> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #define eps 1e-10 #define maxn 1234 using namespace std; struct point { double x,y; } p[maxn]; struct Node{ double l,r; bool flag; }h[maxn]; int n; double d; bool cmp(Node a,Node b) { if(fabs(a.r - b.r) < eps) return a.l < b.l; return a.r < b.r; } double funl(double x,double y) { return x - sqrt(1.0*d*d-y*y); } double funr(double x,double y) { return x + sqrt(1.0*d*d-y*y); } int main() { int time = 0; while(1) { time++; scanf("%d%lf",&n,&d); if(n==0 && d==0) break; for(int i=0; i<n; i++) { scanf("%lf%lf",&p[i].x,&p[i].y); } bool vis = true; for(int i=0; i<n; i++) { if(p[i].y > d) { vis = false; break; } h[i].l=funl(p[i].x,p[i].y); h[i].r=funr(p[i].x,p[i].y); h[i].flag=true; } if(!vis){ printf("Case %d: -1\n",time); continue; } int ans=0; sort(h,h+n,cmp); for(int i=0;i<n;i++){ if(h[i].flag){ ans++; for(int j=0;j<n;j++){ if(h[j].l < h[i].r+eps && h[j].flag == true){ h[j].flag=false; } } } } printf("Case %d: %d\n",time,ans); } return 0; }
相关文章推荐