POJ 1328 放置雷达(贪心,区间)

POJ 1328 Radar Installation-放置雷达

问题:

就是给出n个海岛的坐标和雷达的半径d,雷达只能沿着x轴放置,求出能把所有海岛都覆盖,所需要的最小雷达数。

如果不能满足输出 -1.

n d 为0 0 时结束。

输入:

3 2
1 2
-3 1
2 1

1 2
0 2

0 0

输出:

Case 1: 2
Case 2: 1

分析:

因为雷达的圆心只能在x轴上,所以可以根据每个海岛的坐标、圆的半径,求出能覆盖该海岛的圆的圆心所在的区间。。

把每个海岛的区间都求出来,

然后按照Lelf 或者 Right 从小到大 排序都可以(我是按照Left排序)。

根据贪心原则,第一个雷达一定放在第一个区间的最右端点。让圆的范围尽可能的向右。

如果下一个区间的左端点在雷达的右边,那么sum++,并且雷达更新为这一个区间的右端点。

如果下一个区间的左端点在雷达的左边,sum不变,雷达不变。

如果下一个区间的左端点在雷达的左边,并且右端点也在雷达的左边,那么显然这时候的雷达不能覆盖这个小岛,需要把雷达更新为这个区间的右端点,sum不变。


注意!!!计算后的坐标是会有小数的!!!WA了好几次。

#include <cmath>
#include <cstdio>
#include <algorithm>
#include <iostream>

using namespace std;

struct Node
{
    double Left,Right;
}s[1010];

bool cmp(Node x,Node y)
{
    return x.Left < y.Left;
}

int main()
{
    int n,d;
    int time = 0;
    while(cin>>n>>d && (n != 0 || d != 0))   //这个n d不同时0的条件错了几次,刚开始写成&&了,那样的话是都不能为0。
    {
        time ++;
        double x,y;
        double l;
        int p = 1;
        for(int i = 0;i < n;i ++)
        {
            cin>>x>>y;
            if(y > d && p)
            {
                p = 0;
            }
            else              //存能覆盖该小岛的圆心所在的区间
            {
                l = sqrt(d*d*1.0 - y*y);
                s[i].Left = x - l;
                s[i].Right = x + l;
            }

        }
        if(p)
        {
            int sum = 1;
            sort(s,s + n,cmp);
            double now = s[0].Right;
            for(int i = 1;i < n;i ++)
            {
                if(s[i].Left > now)
                {
                    sum ++;
                    now = s[i].Right;
                }
                else if(s[i].Right < now)
                {
                    now = s[i].Right;
                }

            }
            cout<<"Case "<<time<<": "<<sum<<endl;
        }
        else
            cout<<"Case "<<time<<": -1"<<endl;
    }
	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_41003528/article/details/79923576