《黑书》uva10382喷水装置,贪心经典题

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=15&problem=1323&mosmsg=Submission+received+with+ID+11785741

题意:有n个喷水装置,可以喷出以r为半径的园的水,然后给出一个常为l,宽为w的长方形,求要多少个喷水装置.......

这题水过,很是开心,主要是在精度那里我吸取了黑书第一题的教训,将精度分的很细,所以水了.......

思路:将被喷水的圆转化到长方形上,就是一个个长方形了,然后取这个圆可以在大长方形长所喷水的最大长度,然后按照区间覆盖来贪心就好。区间覆盖的问题,就是说以第起始点为开始点,然后总是取可以覆盖最长的那一段.......不懂的朋友可以看这里:http://www.cnblogs.com/ziyi--caolu/archive/2013/05/19/3087139.html

哦,这个题目最需要注意的地方就是精度问题了.......

#include<iostream>

#include<stdio.h>

#include<string.h>

#include<math.h>

#include<algorithm>

using namespace std;

struct ss

{

	double x,y;

}s[10005];

int cmp(const ss a,const ss b)

{

	if(a.x<b.x)

	return 1;

	else

	return 0;

}

int main()

{

	int n;

	double l,w;

	while(scanf("%d %lf %lf",&n,&l,&w)>0)

	{

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

		{

			double tmp,tmp1;

			scanf("%lf%lf",&tmp,&tmp1);

			if(tmp1<w/2.0-1e-6||fabs(tmp1-w/2.0)<1e-6)

			{

				i--;

				n--;

				continue;

			}

			double x=sqrt(tmp1*tmp1-w*w/4.0);

			s[i].x=tmp-x;

			s[i].y=tmp+x;

			if(s[i].x<1e-6)

			s[i].x=0;

			if(s[i].y>l+1e-6)

			s[i].y=l;

		}

		sort(s,s+n,cmp);

		if(fabs(s[0].x)>1e-6)

		{

			printf("-1\n");

			continue;

		}

		double pos=0,maxx=0;

		int sum=0;

		while(1)

		{

			if(pos>=l)

			break;

			maxx=0;

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

			if((s[i].x<pos-1e-6||fabs(s[i].x-pos)<1e-6)&&s[i].y>pos+1e-6)

			{

				if(s[i].y>maxx+1e-6)

				{

					maxx=s[i].y;

				}

			}

			if(fabs(maxx)<1e-6)

			{

				sum=0;

				break;

			}

			sum++;

			pos=maxx;

		}

		if(sum==0)

		printf("-1\n");

		else

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

	}

	return 0;

}

 

代码:

你可能感兴趣的:(uva)