首页 > 代码库 > Poj 1328(雷达安装)几何+贪心
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 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。