POJ-1328 Radar Installation題解
阿新 • • 發佈:2021-06-16
Radar Installation(貪心)
題意
假設在一條無限延伸的\(x\)軸上方存在\(n\)個點,現問是否能用多個在圓心在\(x\)軸上,半徑為\(d\)的圓包含所有的點,若可以,輸出最少的使用個數,不行則輸出\(-1\)。
思路
先考慮不行的情況,只要點的離\(x\)軸的高度超過圓的半徑\(d\),就不可能用圓來覆蓋。
接下來,我們可以先想一下兩個點的情況,什麼時候需要增加新的圓?設兩個點分別為\(A、B\),並假設\(B\)在\(A\)的右側。能圈住\(A\)點並且向右覆蓋範圍最大的是當\(A\)點在圓上,此時圓心\(X_A\)的位置最靠右,只要\(B\)離圓心的距離大於半徑,並且能圈住\(B\)
參考程式碼
點此展開
#include<iostream> #include<cmath> #include<algorithm> using namespace std; typedef long long LL; typedef pair<int,int> PII; const double eps=1e-6; const int N=1010; struct node { double x,y; bool operator<(const node &a) { return x<a.x; } }ns[N]; double get_pos(double y,double d) { return sqrt(d*d-y*y); } double calc_dis(double cur,double x,double y) { return sqrt(y*y+(x-cur)*(x-cur)); } int main() { #ifdef LOCAL freopen("D:/VSCodeField/C_Practice/a.in", "r", stdin); freopen("D:/VSCodeField/C_Practice/a.out", "w", stdout); #endif int kase=0; int n; double d; while(cin>>n>>d) { if(n==0&&d<eps) break; bool has=false;//是否有點不能被覆蓋 for(int i=0;i<n;i++) { cin>>ns[i].x>>ns[i].y; if(ns[i].y-d>eps) has=true; } cout<<"Case "<<++kase<<": "; if(has) cout<<-1<<endl; else { sort(ns,ns+n); int res=1; double cur=ns[0].x+get_pos(ns[0].y,d); for(int i=1;i<n;i++) { double next_pos=ns[i].x+get_pos(ns[i].y,d); if(calc_dis(cur,ns[i].x,ns[i].y)>d) { if(next_pos>cur) res++; cur=next_pos; } } cout<<res<<endl; } } return 0; }