poj1328 Radar Installation (貪心)
阿新 • • 發佈:2018-12-12
題意
給n個位於x軸上方的點,和一個半徑r,問在x軸上最少多少個圓,可以將所有的點覆蓋。
題解
首先,距x軸距離超過r的,顯然是不可取的。
對於每個點,我們找一個恰能包含該點的,在x軸上最靠右的圓心,
這樣當出現新的列舉右圓心時,
①若出現在該圓心左,
如r=5時,(-4,3)圓心在(0,0),(-3,5)圓心在(-3,0),
那麼更新圓心在-3處即可,對於列舉右圓心,顯然右邊的圓心是不會出現在左圓心以左超過r的位置的。
這樣,更新到(-3,0),就能包含兩個圓。
②若出現在該圓心右,
則由於之前的圓是列舉的最右圓心,略右移即不能包含原來的點,
則只需判斷該點與原圓心距離是否在r以內,
如在r以內則不需新建圓,否則需要另起一圓。
思路來源
程式碼實現
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; int n,r; double nowo; struct node { int x,y; }; node q[1005]; bool cmp(node a,node b) { if(a.x!=b.x)return a.x<b.x; else return a.y>b.y;//同x軸情況下,距x軸更遠,圓心越靠左 } int main() { int cas=0; while(~scanf("%d%d",&n,&r)&&n+r) { int maxy=0,ans=0; for(int i=0;i<n;++i) { scanf("%d%d",&q[i].x,&q[i].y); maxy=max(maxy,q[i].y); } printf("Case %d: ",++cas); if(maxy>r)//有遠離x軸超過半徑的小島 { puts("-1"); continue; } sort(q,q+n,cmp); nowo=q[0].x+sqrt(r*r-q[0].y*q[0].y*1.0); ans++; //初始圓心位置,向右建一個恰能包含該點的圓 for(int i=1;i<n;++i) { double tempo=q[i].x+sqrt(r*r-q[i].y*q[i].y*1.0);//同是向右建圓,故圓心不會出現在上個圓圓心左超過r的位置 if(tempo<nowo)nowo=tempo; else if((nowo-q[i].x)*(nowo-q[i].x)+q[i].y*q[i].y>r*r)//由於這個圓是以某個點建的最右圓心圓,故無法右移圓心,只能判斷距離是否小於r { ans++; nowo=tempo; } } printf("%d\n",ans); } return 0; }