P1325 雷达安装

2017-05-05 16:39

题目描述

描述:

假设海岸线是一条无限延伸的直线。它的一侧是陆地,另一侧是海洋。每一座小岛是在海面上的一个点。雷达必须安装在陆地上(包括海岸线),并且每个雷达都有相同的扫描范围d。你的任务是建立尽量少的雷达站,使所有小岛都在扫描范围之内。

数据使用笛卡尔坐标系,定义海岸线为x轴。在x轴上方为海洋,下方为陆地。

样例1如图所示

输入输出格式

输入格式:

第一行包括2个整数n和d,n是岛屿数目,d是雷达扫描范围。

接下来n行为岛屿坐标。

输出格式:

一个整数表示最少需要的雷达数目,若不可能覆盖所有岛屿,输出“-1”。

输入输出样例

输入样例#1:
3 2
1 2
-3 1
2 1
输出样例#1:
2

 

这是一道贪心的问题,

因为每一个雷达都有一个覆盖半径,而我们需要将所有的点都覆盖

那么我们是不是可以这样想

因为每一个点都需要被覆盖,所以我们需要让每一个点扩充成一个半径是/雷达可以覆盖的半径/的圆

然后再把每一个圆与x轴的交点坐标算出来

这样我们就成功的把这道题转换成了线段覆盖的问题

再把产生的数据按照末尾的结束顺序排序,再在每一个没有访问过的节点的末尾放置一个雷达即可

参考代码:



 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 struct node
 8 {
 9     double x;
10     double y;
11 }a[10001];
12 int n,d;
13 int vis[10001];
14 int ans=0;
15 int comp(const node & a , const node & b)
16 {
17     if(a.y==b.y)return a.x<b.x;
18     else return a.y<b.y;
19 }
20 int main()
21 {
22     scanf("%d%d",&n,&d);
23     for(int i=1;i<=n;i++)
24     {
25         int x,y;
26         scanf("%d%d",&x,&y);
27         if(d<y)
28         {
29             printf("-1");
30             return 0;
31         }
32         double l=sqrt(d*d-y*y);
33         a[i].x=(double)x-l;
34         a[i].y=(double)x+l;
35     }
36     sort(a+1,a+n+1,comp);
37     for(int i=1;i<=n;i++)
38     {
39         if(vis[i]==0)
40         {
41             ans++;
42             for(int j=i;j<=n;j++)
43                 if(a[j].x<a[i].y)vis[j]=1;    
44         }
45     }
46     printf("%d",ans);
47     return 0;
48 }