区间选点问题,难点再与把题意进行转化
这个题题意是说,海上有n多岛,在海岸线上(x轴)建一个雷达能覆盖到与它距离不超过d的岛,求覆盖所有岛的最小雷达数。
注意到能覆盖每一个岛的范围是一定的。即坐标为x,y的岛只能由[x-sqrt(d*d-y*y),x+sqrt(d*d-y*y)]的雷达覆盖。
所以这个题转化成了,对于所有的区间,求最小的点数能使每个区间都至少有一个点,即区间选点问题
对于区间选点问题,白书上写的很详细......
不过我WA了很多次,原因竟然是少写了一个等号!!!囧.......,看别人的代码是按照 左边排序,不过那样就分很多情况,不推荐.....
code
#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <limits>
#include <vector>
#include <bitset>
#include <string>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <string.h>
#include <iostream>
#include <algorithm>
#define Si set<int>
#define LL long long
#define pb push_back
#define PS printf(" ")
#define Vi vector<int>
#define LN printf("\n")
#define lson l,m,rt << 1
#define rson m+1,r,rt<<1|1
#define SD(a) scanf("%d",&a)
#define PD(a) printf("%d\n",a)
#define SET(a,b) memset(a,b,sizeof(a))
#define FF(i,a) for(int i(0);i<(a);i++)
#define FD(i,a) for(int i(a);i>=(1);i--)
#define FOR(i,a,b) for(int i(a);i<=(b);i++)
#define FOD(i,a,b) for(int i(a);i>=(b);i--)
#define readf freopen("input.txt","r",stdin)
#define writef freopen("output.txt","w",stdout)
const int maxn = 1006;
const int INF = ~0U>>1;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
const double pi = acos(-1.0);
using namespace std;
int N,D;
struct point{
double x,y;
}p[maxn];
bool cmp(const point a,const point b){
if(a.y==b.y) return a.x>b.x;
return a.y<b.y;
}
void solve(){
sort(p+1,p+N+1,cmp);
int cnt=1;
// FOR(i,1,N){
// printf("%.5lf %.5lf \n",p[i].x,p[i].y);
// }
double temp=p[1].y;
FOR(i,2,N){
if(p[i].x>temp){
cnt++;
temp=p[i].y;
}
}
printf("%d\n",cnt);
}
int main()
{
// readf;
// writef;
int x,y;
double t;
bool flag;
int cas=1;
while(~scanf("%d%d",&N,&D) &&( N || D )){
flag=true;
FOR(i,1,N){
scanf("%d%d",&x,&y);
if(y<=D && flag){
t=sqrt((double)(D*D-y*y));
p[i].x=x-t;
p[i].y=x+t;
}else{
flag=false;
}
}
printf("Case %d: ",cas);
if(!flag){
puts("-1");
}else{
solve();
}
cas++;
}
return 0;
}