| 基站布置 | ||
|---|---|---|
| Time Limit: 1000 MS | Memory Limit: 1000 KB | |
Description
海面上有一些船需要与陆地进行通信,需要在海岸线上布置一些基站。现将问题抽象为,在x轴上方,给出n条船的 坐标p1,p2,…,pn,其中pi=(xi,yi),0≤yi≤d, 1≤i≤n,在x轴安放的基站可以覆盖半径为d的区域内的所有船只, 问在x轴至少要安放几个基站才可以将x轴上方的船只都覆盖到。![]()
Input
第一行输入m表示有m组测试. 每组测试首先输入两个整数n(n<=10000)和d,接下来输入n个整数坐标(x,y),其中0≤y≤d. 黑色, 其中0和1的个数分别为n个.
Output
对每组测试数据输出所需最少基站个数. 提示: 判断两点距离是否小于d可能需要考虑精度损失, 建议使用 (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) - d*d <= 1e-10 而非 (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) <= d*d
Sample Input
2 3 2 0 1 2 1 3 2 4 4 0 1 1 1 2 1 3 2
Sample Output
2
1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
struct pos_t {
double x, y;
double rsect;
} pos[10010];
int cover[10010];
int n;
double d;
const double minINF = 0.00000000001;//浮点误差
int cmp(const void *a, const void *b) {
pos_t *ta, *tb;
ta = (pos_t *)a;
tb = (pos_t *)b;
double temp = ta->rsect-tb->rsect;
if(-minINF<=temp && temp<=minINF) {//浮点数比较注意预留一定的精度判断
//if(temp == 0) {
return 0;
}
else if (temp < 0) {
return -1;
}
else {
return 1;
}
}
int solve() {
scanf("%d%lf", &n, &d);
for(int i=0; i<n; i++) {
scanf("%lf%lf", &pos[i].x, &pos[i].y);
pos[i].rsect = pos[i].x + sqrt(d*d-pos[i].y*pos[i].y);
}
memset(cover, 0, sizeof(cover));
qsort(pos, n, sizeof(pos_t), cmp);
int count = 0;
for(int i=0; i<n; i++) {
if(cover[i] == 1) {
continue;
}
count = count + 1;
for(int j=i; j<n; j++) {
if(pos[j].rsect-pos[i].rsect > 2*d) {
break;
}
if(cover[j]==1) {
continue;
}
//下面也需要注意浮点误差
double temp = (pos[j].x-pos[i].rsect)*(pos[j].x-pos[i].rsect) + pos[j].y*pos[j].y - d*d;
if(temp<=minINF) {
cover[j] = 1;
}
}
}
printf("%d\n", count);
}
int main() {
int m;
scanf("%d", &m);
for(int i=0; i<m; i++) {
solve();
}
return 0;
}