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

poj1328 贪心

时间:2015-05-21 22:38:48      阅读:203      评论:0      收藏:0      [点我收藏+]

标签: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;
}


poj1328 贪心

标签:poj1328

原文地址:http://blog.csdn.net/fangpinlei/article/details/45896573

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