地址 :http://poj.org/problem?id=1328
思路 :贪心,首先将所有点安装x由小到大排序,再找覆盖当前点的圆的最右圆心,等当前的圆包含不了当前的点就找一个新的圆,一直这样遍历,开始我是直接找当前点的最右圆心,结果一直WA,然后发现这样更新圆心是不对的,例如
遍历时先查询绿点,它的圆心在x1,再遍历到蓝点时发现x1包含不了蓝点,这样的结果就是要2个圆,但是以x2为圆心是绿点和蓝点都可以的,只要一个圆可以了,因此在查询蓝点时,发现x1包含不了蓝点,而蓝点的圆心x2<x1,那么就不用加1,因为当前x1包含的点,x2同样能够包含,只要将x1=x2就行了
Code :
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
struct node{
int x;
int y;
bool operator<(const node &p)const{
return x<p.x;
}
};
const int MAX_N=1005;
LL n,m;
node a[MAX_N];
int main()
{
ios::sync_with_stdio(false);
int t=1;
while(cin>>n>>m){
if(!n&&!m) break;
int ans=1;
for(int i=0;i<n;++i)
{
cin>>a[i].x>>a[i].y;
if(a[i].y>m) ans=-1;
}
if(ans!=-1){
double x0=a[0].x+sqrt(m*m-a[0].y*a[0].y),x1;
sort(a,a+n);
for(int i=0;i<n;++i)
{
LL xi=a[i].x,yi=a[i].y;
if(yi*yi+(xi-x0)*(xi-x0)>m*m){
x1=xi+sqrt(m*m-yi*yi);
if(x1>x0) ans++;
x0=x1;
}
}
}
if(!n) ans=0;
cout<<"Case "<<t++<<": "<<ans<<endl;
}
return 0;
}