POJ1328详细题解

看了大佬的博客才搞懂......

以每个小岛为坐标原点,建立圆,获得与x 轴的左交点 left 与右交点 right,获得了雷达在x轴上可以存在的区间,然后贪心枚举,具体看代码注释

//newStart cy 2019 0907
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iostream>
#include<cmath>
using namespace std;
const int maxn = 1000 + 15;
typedef struct
{
    double left,right;
}point;//雷达在x轴上所能处的范围
point arr[maxn];
bool cmp(const point& p1,const point& p2)
{
    return p1.left < p2.left;//贪心,通过岛屿的位置确定雷达的位置所能处的范围
}
int main()//逆向思维,线段贪心
{
    int n,d;//n个海岛,雷达范围为d
    int kase = 0;
    while(cin>>n>>d)
    {
        if(n==0&&d==0)
            break;
        bool flag = false;//判断是否存在无法覆盖的点
        double x,y;
        for(int i=0;i!=n;++i)
        {
            cin>>x>>y;
            if(y > d)
                flag = true;//存在无法覆盖的点
            arr[i].left = x - sqrt(d*d - y*y);//区间范围的左端点
            arr[i].right = x + sqrt(d*d - y*y);//区间范围右端点
        }
        if(flag)
        {
            cout<<"Case "<<++kase<<": -1"<<endl;
            continue;
        }//剪枝
        sort(arr,arr+n,cmp);
        double right = arr[0].right;
        int ans = 1;//统计雷达数量
        for(int i=1;i!=n;++i)
        {
            if(arr[i].left<=right)  
                right = min(right,arr[i].right);//更新可能改变的区间范围
            else{
                right = arr[i].right;
                ++ans;
            }//在无法覆盖的情况下,更新新的区间范围
        }
        cout<<"Case "<<++kase<<": "<<ans<<endl;
    }
}

  

不怕万人阻挡,只怕自己投降。
原文地址:https://www.cnblogs.com/newstartCY/p/11480333.html