zoukankan      html  css  js  c++  java
  • NYOJ 12 喷水装置(二)

    喷水装置(二)

    时间限制: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。

    例子输入
    2
    2 8 6
    1 1
    4 5
    2 10 6
    4 5
    6 5
    例子输出
    1
    2
    来源
    《算法艺术与信息学竞赛》


    贪心解决这个问题

    #include"stdio.h"
    #include"math.h"
    #include"stdlib.h"
    #define N 100005
    struct node
    {
    	double l,r;     //记录每一个水龙头能灌溉的左右边界
    }f[N];
    int cmp(const void*a,const void*b)
    {
    	return (*(struct node*)a).l<(*(struct node*)b).l?-1:1;
    }          
    int main()
    {
    	int t,n,i,j;
    	double w,h,x,r;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d%lf%lf",&n,&w,&h);
    		h/=2;
    		for(i=0,j=0;i<n;i++)
    		{
    			scanf("%lf%lf",&x,&r);
    			if(r<h)          //半径太小
    				continue;
    			double d=sqrt(r*r-h*h);
    			f[j].l=x-d;
    			f[j++].r=x+d;
    		}
    		n=j;
    		qsort(f,n,sizeof(f[0]),cmp);
    		double rr=0,cur;
    		int cnt=1;
    		for(i=0;i<n;i++)   //从0点取最右边的那个喷水装置
    		{
    			if(f[i].l>0)
    				break;
    			if(rr<f[i].r)
    				rr=f[i].r;
    		}
    		if(rr==0)
    		{
    			printf("0
    ");
    			continue;
    		}	
    		for(cur=0;i<n;i++)
    		{
    			if(rr>=w)  
    				break;
    			if(f[i].l<=rr)     //从交叉地方取一个最右边的那个喷水装置
    			{
    				if(f[i].r>cur)
    					cur=f[i].r;
    			}
    			if(f[i].l>rr)
    			{
    				if(f[i].l>cur)
    				{
    					cnt=0;
    					break;
    				}
    				else
    				{
    					cnt++;
    					rr=cur;
    					cur=0;
    				}
    			}
    		}
    		if(rr<w)  //最后特殊处理边界点  
    		{
    			if(cur<w)
    				cnt=0;
    			else
    				cnt++;
    		}
    		printf("%d
    ",cnt);
    	}
    	return 0;
    }



  • 相关阅读:
    C++中派生类与基类的同名成员调用机制
    一元运算符重载
    二元运算符重载
    const修饰符在不同位置带来的效应
    C++中指针与引用的区别
    基本的查找算法
    排序算法
    指针是怎么回事
    面试总结(1)
    价值观作业
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5086778.html
Copyright © 2011-2022 走看看