对每个岛屿,能覆盖它的雷达位于线段[x-sqrt(d*d-y*y),x+sqrt(d*d+y*y)],那么把每个岛屿对应的线段求出来后,其实就转化成了经典的贪心法案例:区间选点问题。数轴上有n个闭区间[ai,bi],取尽量少的点,使得每个区间内都至少有一个点。选法是:把区间按右端点从小到大排序(右端点相同时按左端点从大到小),然后每个没选的区间选最右边的一个点即可。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<list> #include<deque> #include<vector> #include<algorithm> #include<stack> #include<queue> #include<cctype> #include<sstream> using namespace std; #define pii pair<int,int> #define LL long long int const double eps=1e-10; const int INF=1000000000; const int maxn=1000+10; int n,cas=1; double d,x,y; struct Line { double l,r; bool used; Line(double ll=0,double rr=0,bool uu=false):l(ll),r(rr),used(uu) {} Line(const Line& C) { l=C.l; r=C.r; used=C.used; } bool operator < (const Line& B) const { if(r!=B.r) return r<B.r; else return l>B.l; } } a[maxn]; int main() { //freopen("in2.txt","r",stdin); //freopen("out.txt","w",stdout); while(scanf("%d%lf",&n,&d)==2) { if(n==0&&d==0) break; printf("Case %d: ",cas++); int ans=0; for(int i=0; i<n; i++) { scanf("%lf%lf",&x,&y); if(y>d) { ans=-1; break; } a[i].l=x-sqrt(d*d-y*y); a[i].r=x+sqrt(d*d-y*y); //cout<<a[i].l<<' '<<a[i].r<<endl; a[i].used=false; } if(ans==-1) { printf("-1 "); } else { sort(a,a+n); for(int i=0; i<n; i++) { //cout<<a[i].l<<' '<<a[i].r<<endl; if(a[i].used==false) { a[i].used=true; ans++; for(int j=i+1; j<n; j++) { if(a[j].l<=a[i].r) { a[j].used=true; } else break; } } } printf("%d ",ans); } } //fclose(stdin); //fclose(stdout); return 0; }