题目地址:
http://poj.org/problem?id=1328
描述:
解法:
采用贪心方法。
先排序,原先想“判断下一个坐标能否被上个坐标的圆覆盖”,coos[j].x-sqrtf(d*d-coos[j].y*coos[j].y) <= coos[i].x+sqrtf(d*d-coos[i].y*coos[i].y,后来发现这种想法是错的,比如单独来看,i的圆可以覆盖到i+1和i+2,但其实不存在i的园能同时覆盖i+1和i+2这两个坐标。给出一组数据方便理解:
4 5 //n d -5 3 -3 5 2 3 3 3
后来采用:把每个岛屿来当做雷达的圆心,半径为d,做圆,与x轴会产生两个焦点L和R,这就是一个区间;首先就是要把所有的区间找出来,然后x轴从左往右按L排序,再然后就是所谓的贪心把那些互相重叠的区间去掉就行。
网上(http://www.tuicool.com/articles/7V3MVj)虽然通过了所有用例,但我觉得代码不对。
这个(http://blog.youkuaiyun.com/jun_sky/article/details/7000938)代码我认为是正确的。
代码:(POJ不能用lambda表达式真是wtf)
#include <iostream>
using namespace std;
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <sstream>
#define EACH(it,a) for(auto it=begin(a);it!=end(a);it++)
#define LL long long
#define INF 0x3f3f3f3f
struct scope{
double l;
double r;
}scopes[1000];
bool cmp(scope a,scope b)
{
return (a.r<b.r);
}
int main()
{
//ios_base::sync_with_stdio(0);
#ifdef LJY
freopen("in.txt","r",stdin);
#endif
int i,j,k,n,d,x,y;
for(k=1;;k++){
int ans=0;
cin>>n>>d;
if(n==0 && d==0)
break;
for(i=0;i<n;++i){
cin>>x>>y;
if(y>d || y<0)
ans=-1;
scopes[i].l=x-sqrtf(d*d-y*y);
scopes[i].r=x+sqrtf(d*d-y*y);
}
if(ans!=-1){
sort(scopes,scopes+n,cmp);
i=0;
double t=scopes[0].r;
ans++;
for(i=1;i<n;i++){
if(scopes[i].l>t){
ans++;
t=scopes[i].r;
}else
t=min(scopes[i].r,t);
}
}
cout<<"Case "<<k<<": "<<ans<<endl;
}
return 0;
}