POJ1328Radar Installation

转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1299228061

 

提示:简单的贪心

正确的算法是:要考虑把雷达站放到哪个位置使得包含雷达的区间最多!

写算法的时候要注意,按海岛的横坐标排序(纵坐标是跟随横坐标,但不能对排序构成任何影响)后,第一个雷达建立在区间的右端,然后依次判断每个区间的左端点,如果在最新建立的雷达右面,那么肯定需要一个雷达,而且也建在区间右端。如果左端点在雷达左面,这个时候要考虑区间的右端在雷达的左面还是右面,如果是右面,那雷达位置就不变,如果在左面,那现在的雷达是覆盖不了的,所以要把雷达放在该区间的右端点!因为这样同时不但能覆盖原来的岛,还能覆盖现在的岛

 

标准方法是把每个点的放置雷达的区间求出,然后按照区间排序。排好序后,从左至右看,当发现下一个区间的起始点大于前面所有区间的最小结束点的时候,答案加一。忽视前面走过的所有点后,对后面进行相同的操作(从左至右看,当发现下一个区间的起始点大于左边未被忽视的所有区间的最小结束点的时候,答案加一)。直到结束。但是这样做相对较难实现。

 

 

 1 //Memory Time 
2 //288K 110MS
3
4
5 #include<iostream>
6 #include<math.h>
7 using namespace std;
8
9 const int island_max=1000;
10
11 int main(void)
12 {
13 int i,j;
14 double x[island_max],y[island_max];
15 double num,rad;
16 for(;;)
17 {
18 /*Input end*/
19 cin>>num>>rad;
20 if(!(num&&rad))break;
21
22 static int count=1; //记录case数目
23
24 /*read in coordinate*/
25 bool flag=false;
26 for(i=0;i<num;i++)
27 {
28 cin>>x[i]>>y[i];
29 if(y[i]>rad)
30 flag=true;
31 }
32
33 /*case fail*/
34 if(flag)
35 {
36 cout<<"Case "<<count++<<": -1"<<endl;
37 continue;
38 }
39
40 /*bubble sort*/
41 //这里由于y要随x连带排序,不能简单地使用 快排qsort
42 double temp;
43 for(i=0;i<num-1;i++)
44 for(j=0;j<num-i-1;j++)
45 if(x[j]>x[j+1])
46 {
47 temp=x[j];
48 x[j]=x[j+1];
49 x[j+1]=temp;
50 temp=y[j];
51 y[j]=y[j+1];
52 y[j+1]=temp;
53 }
54
55 double left[island_max],righ[island_max]; //海岛圆在海岸线上的左右交点
56 for(i=0;i<num;i++)
57 {
58 left[i]=x[i]-sqrt(rad*rad-y[i]*y[i]);
59 righ[i]=x[i]+sqrt(rad*rad-y[i]*y[i]);
60 }
61
62 int radar=1;
63 for(i=0,temp=righ[0];i<num-1;i++)
64 if(left[i+1]>temp)
65 {
66 temp=righ[i+1];
67 radar++;
68 }
69 else if(righ[i+1]<temp)
70 temp=righ[i+1];
71
72 cout<<"Case "<<count++<<": "<<radar<<endl;
73 }
74 return 0;
75 }
原文地址:https://www.cnblogs.com/lyy289065406/p/2120512.html