题目大意
在x轴上方有n个点,让你用圆心在x轴上,半径为d的圆覆盖这些点,求最小的圆的个数
典型的区间覆盖问题,运用勾股定理可以计算出海岸线上(x轴)能够覆盖到每一个点的区间(注意,区间边界可能是浮点数,就因为这个被卡了好久,QAQ)接下来的问题可以参考我的另一篇博客
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<cmath>
using namespace std;
struct node{
double l,r;
}a[1001];
bool cmp(node x,node y)
{
if(x.r<y.r)return 1;
if(x.r==y.r)if(x.l<y.l)return 1;
return 0;
}
int getint()
{
int num=0,flag=1;char c;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
return num*flag;
}
int n,d,s;
bool v[1001];
int main()
{
int i,x,y,o=0;
bool p;
n=getint(),d=getint();
while(n)
{
s=p=0;memset(v,0,sizeof v);
for(i=1;i<=n;i++)
{
x=getint(),y=getint();
if(y*y>d*d)p=1;
double hh=sqrt((d*d-y*y)*1.0);
a[i].l=x-hh,a[i].r=x+hh;
}
if(p||d<0){printf("Case %d: -1
",++o);goto hh;}
sort(a+1,a+n+1,cmp);
for(i=1;i<=n;i++)
if(!v[i])
{
double hh=a[i].r;
s++;
while(a[i].l<=hh)v[i]=1,i++;
i--;
}
printf("Case %d: %d
",++o,s);
hh:;
n=getint(),d=getint();
}
}