1. 程式人生 > >poj1328 Radar Installation 貪心 (手動翻譯)

poj1328 Radar Installation 貪心 (手動翻譯)

假設陸地的海岸線是一條無限延長的直線,海島是一個個的點,現需要在海岸線上安裝雷達,使整個雷達系統能夠覆蓋到所有的海島。雷達所能覆蓋的區域是以雷達為圓心半徑為d的圓,我們用指標座標系來描述,海岸線就是x軸,現在給出每個海島的座標與雷達的半徑d,請編寫一個程式計算出最少需要多少個雷達才能夠將所有海島全部覆蓋?

輸入:                              

輸入將會有多組資料,每組資料第一行為n (1<=n<=1000),d,n為海島個數,d為雷達半徑,接下來n行,每行兩個數描述海島座標。以n==0,d==0表示輸入結束

輸出:

每組資料對應一行,輸出最少需要的雷達個數,如果不能滿足,則輸出-1,具體格式見樣例。

樣例輸入:

3 2

1 2

-3 1

2 1

1 2

0 2

0 0

樣例輸出:

Case 1: 2

Case 2: 1

題很坑!大致思路就是把每個點轉換為一條條線段,用區間選點的方法做,很坑,具體見程式碼。


<pre name="code" class="cpp">#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<iostream>  
#include<math.h>  
using namespace std;  
struct seg{  
    double a,b;  
}x[1001];//每一條線段   
int n;  
double d;  
bool cmp(seg a,seg b)  
{  
    if(a.b!=b.b)return a.b<b.b;  
    return a.a>b.a;  
}//按照每一條線段的右端點排序   
int work(double a,double b,int i)  
{  
    if(b>d||b<-d)return 1;//雷達不能覆蓋   
    double dis=sqrt(d*d-b*b);  
    x[i].a=a-dis,x[i].b=a+dis;  
    return 0;  
}  
int main()  
{  
    int num=0;  
    while(cin>>n>>d)  
    {  
        num++;  
        int i,cnt=0,f=0,f1;  
        double j,k;  
        if(!n&&!d)break;  
        memset(x,0,sizeof(x));  
        for(i=1;i<=n;i++)  
        {  
            cin>>j>>k;  
            f1=work(j,k,i);  
            if(f1)f=1;  
        }  
        if(d<0||f)//雷達半徑為負數......也是不能到達的   
        {  
            cout<<"Case "<<num<<": "<<-1<<endl;  
            continue;  
        }  
        sort(x+1,x+n+1,cmp);  
        double end=-0x3f3f3f3f;//橫座標要很小....因為..你懂的   
        for(i=1;i<=n;i++)  
        {  
            if(end<x[i].a)  
            {  
                end=x[i].b;  
                cnt++;  
            }  
        }  
        cout<<"Case "<<num<<": "<<cnt<<endl;  
    }  
}