雷达安置
题目描述:
假设海岸线是一条无限延伸的直线。它的一侧是陆地,另一侧是海洋。每一座小岛是在海面上的一个点。雷达必须安装在陆地上(包括海岸线),并且每个雷达都有相同的扫描范围d。你的任务是建立尽量少的雷达站,使所有小岛都在扫描范围之内。注意,建立雷达站的点的坐标必须为整数。
数据使用笛卡尔坐标系,定义海岸线为x轴。在x轴上方为海洋,下方为陆地。
[image]
输入格式:
第一行包括2个整数n和d,n是岛屿数目,d是雷达扫描范围。
接下来n行为岛屿坐标,均为整数。
输出格式:
一个整数表示最少需要的雷达数目,若不可能覆盖所有岛屿,输出“-1”。
样例输入:
3 2 1 2 -3 1 2 1
样例输出:
2
约定:
n<=1000,d<=20000
-210^6<=xi<=210^6
0<=yi<=20000
WA90
有没有更好的写法?
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int MaxN=1005;
struct segment {
double l,r;
}a[MaxN];
int n;
double d;
int num[MaxN];
inline double calc( double y)
{
return sqrt (d*d-y*y);
}
inline void init()
{
scanf ( "%d%lf" ,&n,&d);
for ( register int i=1;i<=n;i++) {
double x,y;
scanf ( "%lf%lf" ,&x,&y);
if (y>d) { //如果y太大了,说明在哪放都无济于事
printf ( "-1" );
exit (0);
}
double len=calc(y);
a[i].l=x-len;
a[i].r=x+len;
num[i]=1; //这一行和前两行的意思:[l,r]要求有一个点
}
}
bool cmp(segment x,segment y)
{
return x.r<y.r;
}
inline void work()
{
int ans=0;
sort(a+1,a+1+n,cmp); //先排序,按右端点
for ( int i=1;i<=n;i++) { //看每一条区间
double nowr=a[i].r; //这一条区间的右端点。因为放右端点的话就有更大几率影响其他的区间
if (num[i]<=0) continue ; //如果没需求了,就直接跳过
num[i]--; //需求减一
for ( register int j=i+1;j<=n;j++) { //看后面相交的区间
if (a[j].l<=nowr) {
num[j]--; //同样需求减一
}
}
ans++; //代价加一
}
printf ( "%d" ,ans);
}
int main()
{
init(); //初始化出区间
work(); //贪心
}