poj1328 贪心

大意是x轴上方有n个目标点,坐标全为整数,为了扫描到他们,在x轴上安放雷达,每一个雷达扫描半径为d,问至少安放多少雷达。

 

首先想到的是化归。找出每一点在x轴上的扫描边界,即在这个范围内必须有雷达才能扫描到。这样便将问题化归为:给n个闭区间,找出最少的点,保证每个区间至少有一个点。


贪心算法:我们先将问题的区间集合按右端点排序,从最左边的区间开始,如果该区间内雷达为空为空,则选区间最右边的端点放雷达,并删掉左端点在雷达前的区间,进入子问题。

//
//  main.cpp
//  poj1328
//
//  Created by Fangpin on 15/5/21.
//  Copyright (c) 2015年 FangPin. All rights reserved.
//

#include <iostream>
#include <vector>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct Node{
    double l,r;
};
bool cmp(const Node& x,const Node& y){
    return x.r<y.r;
}

int main(int argc, const char * argv[]) {
    // insert code here...
//    std::cout << "Hello, World!\n";
    int n,d,ca=1;
    while(scanf("%d%d",&n,&d),n+d){
        vector<Node> vec;
        vec.clear();
        bool flag=true;
        for(int i=0;i<n;++i){
            int x,y;
            scanf("%d%d",&x,&y);
            if(y>d) flag=false;
            vec.push_back(Node{x-sqrt(d*d-y*y),x+sqrt(d*d-y*y)});
        }
        if(!flag){
            printf("Case %d: -1\n",ca++);
            continue;
        }
        sort(vec.begin(),vec.end(),cmp);
        int cnt=0;
        double pre=-1e10;
        for(int i=0;i<n;++i){
            if(vec[i].l>pre){
                pre=vec[i].r;
                ++cnt;
            }
        }
        printf("Case %d: %d\n",ca++,cnt);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值