Radar Installation / POJ - 1328

Input
The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.
The input is terminated by a line containing pair of zeros
Output
For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.
Sample Input
3 2
1 2
-3 1
2 1
1 2
0 2
0 0
Sample Output
Case 1: 2
Case 2: 1
题意
多组测试数据
给你n个坐标上的点, n <= 1000
你可以在x轴上放置雷达,每个雷达的辐射半径都是d
现在问你辐射到所有的点至少需要几个雷达,如果辐射不到所有的点输出-1
题解
转化为区间问题
已知一点,可求出对应的最短距离的雷达(在X轴上)的位置, 此时雷达覆盖范围在X轴上的左右端点就是区间的左右端点「需要数学公式」。
https://www.cnblogs.com/Little-Turtle--QJY/p/12390466.html
「数学原理!!啦」
代码
#include<bits/stdc++.h>
using namespace std;
struct note{
double l, r;
}a[1005];
bool cmp(note x, note y){
return x.r < y.r;
}
int main(){
int Case = 1;
int n, d, x, y, ans = 0, flag = 0;
double s;
while(scanf("%d%d",&n,&d) == 2){
flag=0;
if(n == 0 && d == 0) break;
for(int i = 1; i <= n; i++){
scanf("%d%d", &x, &y);
if(y > d || y < (-d)){//不管怎么样雷达都无法覆盖这个点
flag = 1;//标记一下
}
if(flag == 0){
a[i].l = x - sqrt(1.0*d*d - y*y);//数学原理
a[i].r = x + sqrt(1.0*d*d - y*y);//同上
}
}
if(flag == 0){
sort(a+1, a+n+1, cmp);//右端点从小到大排序
ans = 0;
s = -(1<<30);
for(int i = 1; i <= n; i++){
if(a[i].l > s){//如果某个雷达的左端点>当前右端点,说明这个雷达要选
ans++;//雷达数+1
s = a[i].r;//更新当前右端点
}
}
}
printf("Case %d: ", Case);
Case++;
if(flag)
printf("-1\n");
else
printf("%d\n", ans);
}
return 0;
}
PS
理解 + 转换 = 简单
没有未来的未来不是我想要的未来

浙公网安备 33010602011771号