POJ 1328

剛剛接觸貪心算法,並不十分理解貪心算法的真正意思.......查閱之,不懂......POJ上找題試試


POJ  1328


    是說在海岸線上怎麼樣才能見最少的雷達覆蓋海中的島嶼,該題轉化爲數學問題就是在x軸上找最少的點,使之可以覆蓋平面上給出的一定數量的點。


    思路就是通過找出每個海島放置雷達的左右區間xl,xr,再按照區間左值xl排序,然後遍歷,當發現下一個端點的xl小於前面已經完成的區間最小右值時,計數器加1,維護最小右值即可。找區間的做法就是以海島爲圓心,雷達覆蓋的距離爲半徑,與x軸相交的兩點分別是xl,xr。


附上代碼以及部分測試數據:

#define MAXN 1005
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
 
typedef struct
{
    int x,y;
}intpoint;//定義儲存點的結構體
 
typedef struct
{
    double xl,xr;
}doupoint;//定義儲存左右值類型的結構體,double
 
intpoint lca[MAXN];
doupoint lr[MAXN];
int n,d,counter;
 
bool cmp(doupoint a,doupoint b)
{
    return a.xl<b.xl;
}
 
bool workout_lr()
{
    int i;
    double min,te;
    for(i=1;i<=n;i++)
    {
        if(lca[i].y>d || lca[i].y<-1*d)
           return false;//遇到不可能的情況,直接跳出
 
        te=sqrt(1.0*(d*d-lca[i].y*lca[i].y));
        lr[i].xr=lca[i].x+te;//求出左右值
        lr[i].xl=lca[i].x-te;
    }
    sort(lr+1,lr+n+1,cmp);
 
    counter=1;min=lr[1].xr;
    for(i=1;i<=n;i++)
    {
        if(lr[i].xl>min){//更新並計數
           counter++;
           min=lr[i].xr;
        }
        else if(lr[i].xr<min)
           min=lr[i].xr;
    }
    return true;
}
 
void solve()
{
    int i,test=1;
    while(scanf("%d %d",&n,&d)==2)
    {
        if(n==0 && d==0) break;
        for(i=1;i<=n;i++)  scanf("%d %d",&lca[i].x,&lca[i].y);
 
        //sort(lca+1,lca+n+1,cmp);
 
        printf("Case %d: ",test++);
        if(workout_lr())  printf("%d\n",counter);
        else printf("-1\n");
    }
}
 
int main()
{
    solve();
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章