POJ1328

题目链接:http://poj.org/problem?id=1328

题目大意:在一条水平线之上有许多岛屿,在其之下是陆地,现在要在水平线上安装一些雷达(同时给你雷达能够覆盖的区域),让所有的岛屿都可以被雷达覆盖,求能够满足要求的雷达的最少数量,当有的岛屿不能覆盖时输出-1。

做题思路:以每个岛屿为中心,给定的半径为半径画圆,有三种情况出现,与水平线有一个交点,有两个节点,没有交点(这种情况输出数出负一即可)前两种情况可以归为一类,既有交点。最后在水平线上会有许多区域,有的区域重合,这时在重合的地方放一个雷达可以同时覆盖多个区域。可以以每组的左交点为基准由小到大排序,这样以第一个的左端点对应的右端点为起始右端点,当下一个重叠区域的右交点小于右端点,更新右端点为现在的右交点,当下一个的左交点大于当前的右端点是雷达树量加一重复以前几步即可。注意本题雷达被放的位置可能不为整数,所以可以定义有关的变量为double型即可。

注意给的测试数据半径可能有负的同时岛屿有在陆地的情况,这两种情况都输出-1.

1 #include <iostream>
2 #include <algorithm>
3 #include <cmath>
4 using namespace std;
5 struct ss{
6 double x,y;
7 }a[1005];
8 int cmp(ss x,ss y)
9 {
10 if(x.x==y.x)return x.y<y.y;
11 else return x.x<y.x;
12 }
13 int main()
14 {
15 int n,i,sum,k,flag;
16 double x,y,m;
17 double tt,ww;
18 k=0;
19 while (cin>>n>>m)
20 {
21 if(n==0&&m==0.0)break;
22 k++;
23 flag=1;
24 sum=0;
25 if(m<0)flag=0;
26 for (i=0;i<n;i++)
27 {
28 cin>>x>>y;
29 if(y>m)flag=0;
30 if(y<0)flag=0;
31 tt=sqrt(m*m-y*y);
32 a[i].x=x*1.0-tt;
33 a[i].y=x*1.0+tt;
34 }
35 if(flag==0)
36 {cout<<"Case "<<k<<": "<<"-1"<<endl;continue;}
37 sort(a,a+n,cmp);
38 sum=1;
39 ww=a[0].y;
40 for (i=1;i<n;i++)
41 {
42 if(a[i].x>ww){
43 sum++;
44 ww=a[i].y;
45 }
46 else if(a[i].y<ww){
47 ww=a[i].y;
48 }
49 }
50 cout<<"Case "<<k<<": "<<sum<<endl;
51 }
52 return 0;
53 }
posted @ 2011-07-03 19:48  我们一直在努力  阅读(416)  评论(0编辑  收藏  举报