码迷,mamicode.com
首页 > 其他好文 > 详细

Poj1328 用雷达覆盖所有的岛屿

时间:2016-11-23 22:50:30      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:半径   .net   第一个   运算   比较大小   img   double   point   通过   

技术分享

(此配图来自http://blog.csdn.net/zhengnanlee/article/details/9613161)

图中ABCD为海岛的位置。题目中会给出几个海岛的坐标位置,雷达覆盖半径d,问你用几个雷达可实现海岛的全部覆盖,不能就输出-1。

观察图可知:(ABCD已经按照左交点数的大小好位置)

A的右交点>B的左交点,所以AB可共用一个雷达;

B的右交点>C的左交点,所以BC可共用一个雷达;

C的右交点<D的左交点,所以CD不可共用一个雷达;

所以一共用2个雷达即可实现岛屿的全部覆盖。

注意,但岛屿的坐标y的绝对值大于时d,根据勾股定理可知,此时的d<r,即圆心以d为半径所画的圆与x轴是没有交点的,

即这个岛屿绝对无法被雷达覆盖,所以可以直接跳出循环,输出-1。

#include <iostream>  
#include <algorithm>  
#include <stdlib.h>  
#include <math.h>   
using namespace std;  
 

//设圆心为point
struct point    
{  
    double left;   //左交点
    double right;  //右交点
}p[2010], temp;  //p[2010]为圆心数组,temp为指针
  

//定义小于的运算。代表sort()的排序对象是各圆心与x轴的左交点。
bool operator < (point a, point b)    
{
    return a.left < b.left;  
}  
  
int main()  
{  
    int n;  
    double r;  
    int kase =1;  
    while (cin >> n >> r )
    {  
        if(n==0&&r==0)
        {
            break;
        }

        bool flag = false;  
        //通过输入的各圆心坐标求出各自与x轴的左右交点坐标
        for (int i = 0; i < n; i++)  
        {  
            double a, b;      //x=a,y=b;
            cin >> a >> b;  
            if (fabs(b) > r)  //y=b>r表示此时的圆心以r为半径画的圆与x轴没有交点
            {  
                flag = true;  
            }  
            else  
            {  
                p[i].left = a * 1.0 - sqrt(r * r - b * b);   //左交点
                p[i].right = a * 1.0 + sqrt(r * r - b * b);  //右交点
            }  
        }  
        cout << "Case " << kase++ << ": ";  
        if (flag)  //代表有的圆与x轴没有交点,即无法实现岛屿的全部覆盖
        {  
            cout << -1 << endl;  
        }  
        else  
        {  
            int countt = 1;  
            sort(p, p + n);    //对数组p[n]里面的左右交点进行排序
            temp = p[0];       //用指针temp指向第一个数组元素的地址

            //对当前指针指向的圆心的右交点 与 下一个元素的左交点进行比较大小  
            for (int i = 1; i < n; i++)  
            {  
                if (p[i].left > temp.right)  //如果下一个圆心的左交点>此时圆心的右交点
                {  
                    countt++;                //则当前的雷达数无法实现所有圆心的覆盖,需要多加1个雷达进行覆盖下一个圆心。
                    temp = p[i];             //此时指针指向数组的下一个元素
                }  
                else if (p[i].right < temp.right)  //如果下一个圆心的左交点<此时圆心的右交点
                {  
                    temp = p[i];                   //则当前的雷达数可以实现所有圆心的覆盖,即可以覆盖到下一个圆心。
                }  
            }  
            cout << countt << endl;  
        }  
    }  
}  

 

Poj1328 用雷达覆盖所有的岛屿

标签:半径   .net   第一个   运算   比较大小   img   double   point   通过   

原文地址:http://www.cnblogs.com/Strugglinggirl/p/6095256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!