Poj 1328(雷达安装)几何+贪心

【题目描述】:

给定n个小岛以及这些小岛的位置,并输入雷达的辐射面积,问最少需要多少个雷达站才能覆盖所有小岛?

【思路分析】:

本题首先想到的是运用贪心算法,但是算法想到了如何贪心?这道题我自己开始做之时只有一点思路,就是让每一个雷达覆盖较多的点,但是如何较多覆盖,这就是典型的数学问题了,自己没有思索出来,最后在网上看了题解才明白如何做。下面我们看看如何建图:

我们通过这个图首先运用了一个数学知识,就是以小岛为圆心,雷达辐射范围为圆心建立一个圆,该圆与x轴有一个交点,以该交点作为雷达站铺设点那么该雷达站一定可任意覆盖小岛。同时如果以各个小岛为圆心建立的圆如果不相交,那么肯定要多个雷达站,如果某一个小岛为圆心的圆与x轴的右交点比另外一个小岛为圆心的圆的右交点小,那么这两个小岛一定可以被同一个雷达覆盖。

当然我们在处理数据的时候,我们需要对数据进行排序。

【AC代码】:

 1 #include<iostream>
 2 #include<math.h>
 3 #include<algorithm>
 4 using namespace std;
 5 #define max 1005
 6 struct radar
 7 {
 8     double left;
 9     double right;
10     double  x;
11     double y;
12 }r[max];
13 int cmp(radar a,radar b)
14 {
15     return a.left<b.left;//对小岛构成的圆与x轴的左交点进行从小到大的排序
16 }
17 int main()
18 {
19     int count=1,n,d;
20     while(cin>>n>>d&&(n||d))
21     {
22         int flag=0,sum=1;
23         double x,y;
24         for(int i=0;i<n;i++)
25         {
26             cin>>x>>y;
27             if(y>d) flag=1;
28             r[i].x=x;
29             r[i].y=y; 
30         }
31         
32         for(int i=0;i<n;i++ )
33         {
34             r[i].left=r[i].x*1.0-sqrt(d*d-r[i].y*r[i].y) ;//计算圆与x轴的左右交点
35             r[i].right=r[i].x*1.0+sqrt(d*d-r[i].y*r[i].y) ;
36         }
37         sort(r,r+n,cmp);
38         if(flag) {cout<<"Case "<<count++<<": -1"<<endl;continue;}
39         double temp=r[0].right;
40         for(int i=1;i<n;i++)
41         {
42             if(r[i].left>temp)
43             {
44              sum++;temp=r[i].right;  //如果两个圆不相交,那么雷达数目加1. 
45             }
46             else if(r[i].right<temp)
47             {
48                 temp=r[i].right;//如果某一个圆的右交点比令一个圆的右交点小,那么更新圆。
49             }
50         }
51         cout<<"Case "<<count++<<": "<<sum<<endl;
52     }
53     return 0;
54 }

 

posted @ 2014-08-03 22:52  future_hero  阅读(1525)  评论(0编辑  收藏  举报