传送门
贪心
题意
给
个点的坐标(
) 然后圆的半径为
圆心只能在
轴上 然后要让最小数量的圆包围所有点
输出
若不能覆盖输出-1
题解
感觉这道题还是很???..
一开始糊了个算法 感觉是对的 然后也没怎么验证算法的正确性啊?>>>
然后还有一些智障的代码错误 然后RE WA了
发
在我
了
发之后 我发现自己智障般的错误。。
之后又WA了
发之后 我终于发现自己的算法错了!!...
一开始糊的是先从左到右排个序 然后尽量让点在圆的边上…..
这当然是错的咯…
其实应该先算出能覆盖该点的圆心可以在的位置的
那么我们就转换成了经典的贪心问题
最少点覆盖区间
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define db double
using namespace std;
const int N=1005;
const db eps=1e-12;
struct data{
db x,y;
}qx[N];
struct node{
db l,r;
}gg[N];
int vis[N];
db d;
int D,cse=0,n;
bool comp(node xx,node yy){
return xx.r<yy.r;
}
bool check(db x){
return x>eps;
}
int main(){
while(scanf("%d%d",&n,&D)==2&&(n||D)){
d=D;
int flag=0;
for(int i=1;i<=n;++i){
scanf("%lf%lf",&qx[i].x,&qx[i].y);
if(qx[i].y-d>eps) flag=1;
}
if(flag) {
printf("Case %d: -1\n",++cse);
continue;
}
for(int i=1;i<=n;++i){
db temp=sqrt(d*d-qx[i].y*qx[i].y);
gg[i].l=qx[i].x-temp;
gg[i].r=qx[i].x+temp;
}
sort(gg+1,gg+1+n,comp);
int ans=0;
for(int i=1;i<=n;++i){
if(!vis[i]){
for(int j=i;j<=n;++j)
if(!vis[j]&&gg[j].l<=gg[i].r) vis[j]=1;
ans++;
}
}
for(int i=1;i<=n;++i) vis[i]=0;
printf("Case %d: %d\n",++cse,ans);
}
return 0;
}
这么智障以后怎么成为大气呀…