zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x07贪心 POJ1328

    题目链接:http://poj.org/problem?id=1328

    给出平面上N个点,要求在横轴上放置最少的点来覆盖N个点,其中每个点的覆盖半径都是R,可以将问题转化成用点覆盖线段的问题,计算N个点中每个点的可被管辖区间,

    转化成求每个线段中至少有一个点的最少的点数。贪心思想。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn 100010
    const double eps=1e-6;
    struct node{
        int x,y;
        double l,r;//l,r为能够管辖这个点的区间 
        bool operator < (const node& a)const {
            return l<a.l;//按照左端点进行升序排序 
        }
    }a[maxn];
    int n,d;
    int main (){
        int kase=0;
        while(cin>>n>>d){
            if(n==0 && d==0)break;
            for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
            bool flag=true;
            for(int i=1;i<=n;i++){
                if(a[i].y>d){
                    flag=false;
                    break;
                }
                double k=sqrt((double)d*d-(double)a[i].y*a[i].y);
                a[i].l=a[i].x-k,a[i].r=a[i].x+k;
            } 
            if(!flag){
                cout<<"Case "<<++kase<<": "<<-1<<endl;
                continue;
            }
            sort(a+1,a+n+1);
            int ans=0;
            double pos=-1e10;
            for(int i=1;i<=n;i++){
                if(pos+eps<a[i].l){//浮点数无法严格比较 
                    ans++;//重新开一个段 
                    pos=a[i].r;
                }else{
                    pos=min(pos,a[i].r);//在满足第i个区间的情况下,使点尽量靠后,之前能覆盖的点不受影响 
                }  
            }
            printf("Case %d: %d
    ",++kase,ans);
        }
    }
  • 相关阅读:
    需求分析和典型用户场景
    WinRT IO相关整理
    C# event线程安全
    DDPush-任意门推送-概述
    IDEA推荐插件
    U盘安装win7系统
    Handlebars.js中集合(list)通过中括号的方式取值
    搭建spring boot+elasticsearch+activemq服务
    HTML IMG标签SRC为null
    JHipster的安装
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13139363.html
Copyright © 2011-2022 走看看