看了大佬的博客才搞懂......
以每个小岛为坐标原点,建立圆,获得与x 轴的左交点 left 与右交点 right,获得了雷达在x轴上可以存在的区间,然后贪心枚举,具体看代码注释
//newStart cy 2019 0907 #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<iostream> #include<cmath> using namespace std; const int maxn = 1000 + 15; typedef struct { double left,right; }point;//雷达在x轴上所能处的范围 point arr[maxn]; bool cmp(const point& p1,const point& p2) { return p1.left < p2.left;//贪心,通过岛屿的位置确定雷达的位置所能处的范围 } int main()//逆向思维,线段贪心 { int n,d;//n个海岛,雷达范围为d int kase = 0; while(cin>>n>>d) { if(n==0&&d==0) break; bool flag = false;//判断是否存在无法覆盖的点 double x,y; for(int i=0;i!=n;++i) { cin>>x>>y; if(y > d) flag = true;//存在无法覆盖的点 arr[i].left = x - sqrt(d*d - y*y);//区间范围的左端点 arr[i].right = x + sqrt(d*d - y*y);//区间范围右端点 } if(flag) { cout<<"Case "<<++kase<<": -1"<<endl; continue; }//剪枝 sort(arr,arr+n,cmp); double right = arr[0].right; int ans = 1;//统计雷达数量 for(int i=1;i!=n;++i) { if(arr[i].left<=right) right = min(right,arr[i].right);//更新可能改变的区间范围 else{ right = arr[i].right; ++ans; }//在无法覆盖的情况下,更新新的区间范围 } cout<<"Case "<<++kase<<": "<<ans<<endl; } }