描述 有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
输入
第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
输出
每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。
样例输入
2
2 8 6
1 1
4 5
2 10 6
4 5
6 5
样例输出
1
2

 这个题我做了两三天一直是wa,基本思路很简单,贪心。用勾股定理求出能覆盖的左右范围,然后从小到大给左端点排序。

一不小心,但总是出现各种各样的错误,被坑死了。

代码如下。

 
#include<stdio.h>
#include<algorithm>
using namespace std;
#include<math.h>
#include<string.h>
struct note
{
    double xi,ri;
} q[10050];
struct doll
{
    double star,end;
} r[10050];
int fun(doll a,doll b)
{
    return a.star<b.star;
}
int main()
{
    int m;
    scanf("%d",&m);
    while(m--)
    {
        double w,h,t;
        int n,i,j,f=1,sum=0;
        scanf("%d%lf%lf",&n,&w,&h);
        j=0;
        for(i=0; i<n; i++)
        {
            scanf("%lf%lf",&q[i].xi,&q[i].ri);
            if(q[i].ri>=(h/2))
            {
                t=sqrt(q[i].ri*q[i].ri-(h/2)*(h/2));
                r[j].star=q[i].xi-t;

                r[j++].end=q[i].xi+t;
            }
        }
        sort(r,r+j,fun);
        double l=0,max;
        while(l<w)
        {
            max=0;
            for(i=0; i<n&&r[i].star<=l; i++)
            {
                if((r[i].end-l)>max)        //每次循环均找出最大的覆盖范围。
                {
                    max=r[i].end-l;
                }
            }
            if(max==0)
            {
                f=0;
                break;
            }
            else
            {
                l=max+l;
                sum++;
            }
        }
        if(f==1)
        {
            printf("%d\n",sum);
        }
        else
        {
            printf("0\n");
        }
    }
    return 0;
}
        


posted on 2017-04-15 16:47  zitian246  阅读(123)  评论(0编辑  收藏  举报