poj 1328 贪心算法和快排(快排细节)

把海岸线看做直线,海上有小岛,岸上有雷达站
雷达站只能覆盖半径为d的区域
把地图看做直角坐标系,海岸线为X轴,陆地在下面
给定小岛坐标和雷达站的覆盖半径。
任务是建立最小的雷达站以覆盖所有的小岛
多测试
n d
n line
换行开始下个test
-1表示无解

思路:把每一个小岛当做半径为d的圆的圆心,算出圆与x轴的交点。记录左右两个坐标,进行快排后,区间重叠的个数就是雷达站个数。思路很简单,但是我在这题奉献了不少WA,原因是没弄清qsort的返回值,qsort的返回值是整形,所以在对double型数据排序的时候要注意返回值的问题,所以qosrt得cmp就得改变为:
int cmp(const void *a,const void *b)
{ 
    return ((double *)a)[0]>((double *)b)[0] ?1:-1;
}
也就是加了个  ? 1 :- 1 ;这样就能限定返回值是整数了。这样就不会WA了
贴上用数组实现和用结构实现的AC代码和测试数据,同时我也会更新代码集中的代码。
#include<stdio.h>
#include<string.h>
#include <iostream>
#include<queue>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define maxn 1005
int cmp(const void *a,const void *b)
{
    return ((double *)a)[0]>((double *)b)[0] ?1:-1;
}
double dir[maxn][2];
int main()
{
    int n,ans;
    double d;
    int ca=1;
    while(scanf("%d %lf",&n,&d)!=EOF)
    {
        if(n==0&&d==0)
            return 0;
        int jg=0;
        for(int i=0; i<n; i++)
        {
            double tmp1,tmp2;
            scanf("%lf %lf",&tmp1,&tmp2);
            if(tmp2>d)
                jg=1;
            double tmp3=sqrt(d*d-tmp2*tmp2);
            dir[i][0]=tmp1-tmp3;
            dir[i][1]=tmp1+tmp3;
        }
        if(!jg)
        {
            qsort(dir,n,sizeof(dir[0]),cmp);
            /*for(int i=0;i<n;i++)
                printf("%lf\n",dir[i][0]);*/
            double l=dir[0][0];
            double r=dir[0][1];
            ans=1;
            for(int i=1; i<n; i++)
            {
                if(dir[i][0]>r)
                {
                    ans++;
                    l=dir[i][0];
                    r=dir[i][1];
                }
                else if(dir[i][1]<r)
                {
                    l=dir[i][0];
                    r=dir[i][1];
                }
            }
        }
        else
            ans=-1;
        printf("Case %d: %d\n",ca,ans);
        ca++;
    }
}
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <iostream>
#include<queue>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define maxn 1005
typedef struct Node{double xr;double xl;} ode;
ode node[maxn];
int cmp(const void *a,const void *b)
{
    return ((ode *)a)->xl>((ode *)b)->xl? 1:-1;
}
int main()
{
    int n,ans;
    double d;
    int ca=1;
    while(scanf("%d %lf",&n,&d)!=EOF)
    {
        if(n==0&&d==0)
            return 0;
        int jg=0;
        for(int i=0; i<n; i++)
        {
            double tmp1,tmp2;
            scanf("%lf %lf",&tmp1,&tmp2);
            if(fabs(tmp2)>d)
                jg=1;
            node[i].xl=tmp1*1.0-sqrt(d*d-tmp2*tmp2);
            node[i].xr=tmp1*1.0+sqrt(d*d-tmp2*tmp2);
        }
        if(!jg)
        {
            qsort(node,n,sizeof(node[0]),cmp);
            //for(int i=0;i<n;i++)
                //printf("%lf\n",node[i].xl);
            ode tmp=node[0];
            ans=1;
            for(int i=1; i<n; i++)
            {
                if(node[i].xl>tmp.xr)
                {
                    ans++;
                    tmp=node[i];
                }
                else if(node[i].xr<tmp.xr)
                {
                    tmp=node[i];
                }
            }
        }
        else
            ans=-1;
        printf("Case %d: %d\n",ca,ans);
        ca++;
    }
}

大神的测试数据:
测试数据,来源于poj讨论组

2 5-3 4-6 34 5-5 3-3 52 33 320 8-20 7-18 6-5 8-21 8-15 7-17 5-1 5-2 3-9 61 22 33 44 55 66 77 88 79 610 50 02 30 22 32 30 21 33 31 2-3 22 48 52 4-4 4-3 3-3 1-3 0-1 00 56 03 01 2-3 12 13 21 2-3 12 11 20 22 30 22 34 -54 34 32 36 -93 -31 2-3 22 16 21 21 21 2-3 12 10 01 20 22 30 21 33 101 102 34 53 51 102 34 54 71 102 34 50 03 91 102 34 52 50 38 30 0

运行结果:

Case 1: 1
Case 2: 2
Case 3: 4
Case 4: 1
Case 5: 1
Case 6: -1
Case 7: 3
Case 8: -1
Case 9: 2
Case 10: 1
Case 11: 1
Case 12: -1
Case 13: -1
Case 14: 2
Case 15: 1
Case 16: 1
Case 17: 1
Case 18: -1
Case 19: -1
Case 20: -1
Case 21: 1





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值