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;
}


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