Uva-10382-Watering Grass

算是比较简单的贪心题嘛,我却WA了一天。最后发现居然是输入位置和半径的时候应该用double,最开始以为用int,无限郁闷。

其实就是说每次找圆的时候尽量找到能够覆盖当前的左边的点并且右边能覆盖最远距离的点即可,其实就是按每个圆能够覆盖的起始位置进行排序,另外需要特殊处理下当r<l/2的圆,因为这些圆无论如何也没办法覆盖到线上。

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=10e5+10;
struct node
{
    double p;
    double ri;
    double l,r;
    bool operator < (const node& a)const
    {
	return l<a.l;
    }
}a[maxn];
int main()
{
    int n,l;
    double w;
    while(scanf("%d%d%lfd",&n,&l,&w)!=EOF)
    {
	double sy=(w/2.0)*(w/2.0);
	for(int i=0;i<n;i++)
	{
	    scanf("%lf%lf",&a[i].p,&a[i].ri);
	    if(a[i].ri*2<w)
	    {
		i--;n--;
	    }
	    else
	    {
		double dis=sqrt(a[i].ri*a[i].ri*1.0-sy);
		a[i].l=a[i].p-dis;
		a[i].r=a[i].p+dis;
		if(a[i].l<0)
		    a[i].l=0;
		if(a[i].r>l)
		    a[i].r=l;
	    }
	}
	sort(a,a+n);
	int ans=0,i=0,index=0,f=1,flag=0;
	double st=0;
	if(a[i].l==0)
	{
	    while(i<n&&a[i].l==0)
	    {
		if(a[i].r>a[index].r)
		    index=i;
		i++;
	    }
	    int maxi=index,t=index;
	    while(a[index].r<l)
	    {
		f=1;
		while(t+1<n&&a[t+1].l<=a[index].r)
		{
		    f=0;
		    ++t;
		    if(a[t].r>a[maxi].r)
			maxi=t;
		}
		t=maxi;index=maxi;
		ans++;
		if(f)
		{
		    flag=1;
		    break;
		}

	    }
	    if(!flag)
		printf("%d\n",ans+1);
	    else
		printf("-1\n");
	}
	else
	    printf("-1\n");
    }
    return 0;
}


你可能感兴趣的:(greedy)