POJ1328详细题解
看了大佬的博客才搞懂......
以每个小岛为坐标原点,建立圆,获得与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;
}
}
不怕万人阻挡,只怕自己投降。
posted on 2019-09-07 13:33 chengyulala 阅读(856) 评论(0) 收藏 举报
浙公网安备 33010602011771号