喷水装置(二)

喷水装置(二)

时间限制:3000 ms  |  内存限制:65535 KB

难度:4

描述

有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。

输入

第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。

输出

每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。

样例输入

22 8 61 14 52 10 64 56 5

样例输出

12

题解:

如果没有坐标限制,直接贪心,每次取能覆盖最大的,直至全部覆盖,其解即为最优解.

有了坐标限制,那么可以按照这样的策略进行贪心,先对每个喷水装置以左区间的值进行从小到大排序(从左边开始覆盖,进行选择)

贪心过程:

选择的喷水装置左区间必须小于或等于当前已经覆盖的长度,否则这样会有空隙.对喷水装置所能覆盖的右区间进行筛选,选择往右覆盖最大的加入最优解中,如果最大往右覆盖为0且没有完全覆盖,则表明不存在方案.

程序代码:

#include<stdio.h>

#include<string.h>

#include<math.h>

#include<algorithm>

using namespace std;

 

struct ps 

{

  double left;//**左交点**// 

  double right;//**右交点**//       

}w[10001];

 

bool comp(ps a,ps b)

{

  if(a.left<b.left)

    return true;

  else

    return false;     

}

 

int main()

{

  int i,N,n,width,high,x,r,count,flag;

  double len,sum,max;

  scanf("%d",&N);

  while(N--)

  {

    sum=0;count=0;flag=1;

    scanf("%d%d%d",&n,&width,&high);

    for(i=0;i<n;i++)

    {

      scanf("%d%d",&x,&r);

      len=(double)r*r-(double)(high/2)*(high/2);  

      if(len<0)  len=0;

      if(len>=0)

        len=sqrt(len);

      w[i].left=x-len;

      w[i].right=x+len;            

    }

    sort(w,w+n,comp);

    while(sum<width)

    {

      max=0;

      for(i=0;i<n && w[i].left<=sum;i++)

        if(w[i].right-sum>max)

          max=w[i].right-sum;           

      if(max==0)

      {

        flag=0;

        break;          

      }

      else

      {

        sum=sum+max;

        count++;    

      }                

    }

    if(flag==0)

      printf("0\n");

    else

      printf("%d\n",count);   

    }          

  system("pause");

  return 0;

}

 


                                       

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值