bzoj4101[Usaco2015 Open]Trapped in the Haybales

来源:互联网 发布:淘宝改差评怎么改 编辑:程序博客网 时间:2024/06/16 14:32

分析:这题目难得一见的好题。。我怎么感觉到了#2题目都变难了一些。。
一开始硬是没搞清楚样例怎么算的。。然后突然看见题目中:贝西可以走到干草堆上。????woc蜜汁能走上去不能走过去?
。。然后才懂。。他的意思是贝西可以走到一个干草堆上然后向另外一个干草堆冲刺。。(有毒)
那么可以列个式子:假设只增加左边干草堆的大小,增加d,左边干草堆编号为i,右边为j
那么可以列式子:size[i]+d>=x[j]-x[i],这个比较明显了。然后移项,然后就会发现你要尽量增大size[i]+x[i],但是x[i]又不能太小,所以二分x[i]。
反过来也是一样的:size[i]+d>=x[i]-x[j]。

code:

#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;typedef long long ll;int n,m;const int N=1e5+5;struct node{    int s,x;}a[N];bool cmp(node x,node y){    return x.x<y.x;}int f[N];int main(){    int s;    scanf("%d%d",&n,&s);    fo(i,1,n)    {        scanf("%d%d",&a[i].s,&a[i].x);    }    a[++n].x=s;    sort(a+1,a+1+n,cmp);    fo(i,1,n)    {        if (a[i].x==s)        {            m=i;            break;        }    }    f[m]=-1<<30;    int ans=1<<30;    fd(i,m-1,1)f[i]=max(f[i+1],a[i].x+a[i].s);//size[i]+d>=x[j]-x[i]    fo(i,m+1,n)f[i]=max(f[i-1],a[i].s-a[i].x);//size[i]+d>=x[i]-x[j]    fo(i,m+1,n)//f[i]=size[i]+x[i],erfen:x[j]-d    {        int l=1,r=m;        while(l<r)        {            int mid=(l+r)>>1;            if (a[i].x-a[mid].x<=a[i].s)r=mid;            else l=mid+1;        }        if (r<m)ans=min(ans,max(0,a[i].x-f[r]));    }    fo(i,1,m-1)    {        int l=m+1,r=n+1;        while(l<r)        {            int mid=(l+r)>>1;            if (a[mid].x-a[i].x<=a[i].s)l=mid+1;            else r=mid;        }         if (l>m+1)ans=min(ans,max(0,-a[i].x-f[l-1]));    }    if (ans==1<<30)printf("-1");    else printf("%d",ans);}
0 0
原创粉丝点击