avatar
fireworks99
keep hungry keep foolish

POJ 1328 Radar Installation(贪心)

Description

x轴上方有N个岛屿,现在要在x轴上安装尽可能少的雷达(覆盖半径为d)来覆盖所有岛屿,求最少雷达数目

Analyze

思维定势,先想到确定最优雷达位置覆盖第一个岛屿,再检测该雷达是否能覆盖其余岛屿,能则测试下一个岛屿,不能则放下一个雷达,后来实现起来麻烦且难做对。

逆向思维:根据岛屿位置推出雷达可放范围

得到一个个区间,问题转化为用最少的点占领所有的区间(保证每个区间上都有个被选中的点),画图得出贪心选择方案

什么时候需运用逆向思维

问题涉及两个相互依赖的事物,按照定势思维想不清楚,则站在另一个对立的角度想想,大胆猜测。问题在于很多时候我们并不能意识到自己的思维定势

Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

struct node
{
    double x, y;
}a[1005];

struct interval
{
    double l, r;
}b[1005];

bool cmp(interval a, interval b)
{
    return a.l < b.l;
}

int main()
{
    int n, cnt = 1;
    double d;
    while(~scanf("%d%lf", &n, &d))
    {
        if(n == 0 && d == 0)
            break;
        bool flag = 1;
        for(int i = 0; i < n; ++i)
        {
            scanf("%lf%lf", &a[i].x, &a[i].y);
            if(a[i].y > d)
                flag = 0;
        }

        if(!flag)
        {
            cout << "Case " << cnt++ << ": ";
            cout << "-1" << '\n';
        }
        else
        {
            for(int i = 0; i < n; ++i)
            {
                double tem = sqrt(d * d - a[i].y * a[i].y);
                b[i].l = a[i].x - tem;
                b[i].r = a[i].x + tem;
            }
            sort(b, b + n, cmp);
            double right = b[0].r;
            int pos = 1, ans = 1;
            while(pos < n)
            {
                while(b[pos].l <= right)
                {
                    right = min(right, b[pos].r);
                    pos++;
                }
                if(pos < n)
                {
                    ans++;
                    right = b[pos].r;
                }
            }
            cout << "Case " << cnt++ << ": ";
            cout << ans << '\n';
        }
    }
    return 0;
}
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy