1. 程式人生 > >【演算法競賽進階指南】貪心POJ3128Radar Installation

【演算法競賽進階指南】貪心POJ3128Radar Installation

本題目是一道經典的覆蓋問題
關於本題目要注意的問題是其中的變數有陷阱,就像做數學題一樣
另外就是關於覆蓋的問題,因為是貪心,首先要去求出來每個建築所需要覆蓋的監控的區間
其次就是對區間的左側進行排序,還需要一個pos進行維護當前安裝監控的位置,一般是區間右側
每次安裝需要看pos和l[i]的關係,如果pos<[i],安裝,同時更新位置
否則,直接需要min(pos,r[i]),如果無需安裝,但是監控的右側位置小於pos,則需要更新監控位置,不然監控管不了new的建築了

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

struct node{
    double l,r;
}radar[1005];

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

int main(){
    int n,d;
    int casen=1;
    while(cin>>n>>d && n!=0 && d!=0){
        bool flag=false;
        if(d<0) {cout<<"Case "<<casen++<<": -1\n";continue;}
        for(int i=1;i<=n;i++){
            int x,y;
            cin>>x>>y;
            if(y>d||y<0){flag=true;}
            radar[i].l=x-sqrt(d*d-y*y);
            radar[i].r=x+sqrt(d*d-y*y);
        }
        if(flag) {cout<<"Case "<<casen++<<": -1\n";continue;}
        sort(radar+1,radar+n+1,cmp);
        double pos=-0x3f3f;
        int ans=0;
        for(int i=1;i<=n;i++){
            if(radar[i].l>pos){
                ans++;
                pos=radar[i].r;
            }else{
                pos=min(radar[i].r,pos);
            }
        }
        cout<<"Case "<<casen++<<": "<<ans<<"\n";
    }
    return 0;
}