动态仙人掌(dinosaur )

pic1
pic2


【分析】

这道题在考场看到我是完全的蒙蔽的,惊人的妄想着能否用数据离散化后的dp来骗分。。。
我果然很菜。。。

好吧,对于我这种菜鸡来说,正解似乎有些难想,让我们考虑从最基本的情况开始考虑。先将所有仙人掌按p为第一关键字排序,从左向右扫。这里我们考虑一个贪心策略,如果仙人掌两两之间距离足够远,则仙人掌之间跳跃的最小高度一定为最高仙人掌的高度。 关于两个相邻的仙人掌如果可以下落再上跳,则到下一个仙人掌的高度就为它自身的高度。否则就不下落一路上升。

不难发现上述贪心策略如果碰到的下下个仙人掌的高度的高度差,大于它与下个仙人掌的距离差,就很容易出现一种无解情况。难道,这道题目贪心就无法完成 WA AC的使命吗?

再次观察题目(这就是不能好好利用题目信息的惨痛教训),稍加思考,我们发现关于每棵仙人掌的那些不可能越过的点(不考虑上下的方向),恰好关于仙人掌形成两个tan为1的等腰直角三角形,如图
pic3
这里我们可以以每个三角形的左端点为关键字排序。如果到第i棵仙人掌的左端点在原有区间的右端点的右边,区间最左边就为p[i]-h[i],最右边就为
p[i]+h[i],同时用仙人掌的高度更新最大高度。反之,就不能下落,且需要构造一个更大的三角形,以跳过这段区间中的所有仙人掌。

下方代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
struct node{
    double p,h;
}a[301000];
bool cmp(node x,node y){
    return x.p-x.h<y.p-y.h;
}
double ans=0;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf",&a[i].p,&a[i].h);
        if(a[i].h>a[i].p){
            cout<<-1<<endl;
            return 0;
        }
    }
    sort(a+1,a+n+1,cmp);
    double minn=a[1].p-a[1].h;
    double maxx=a[1].p+a[1].h;
    for(int i=2;i<=n;i++){
        if(a[i].p-a[i].h>=maxx){
            minn=a[i].p-a[i].h;
            maxx=a[i].p+a[i].h;
            ans=max(ans,a[i].h);
        }
        else{
//          minn=min(minn,(a[i].p-a[i].h));
            maxx=max(maxx,(a[i].p+a[i].h));
            ans=max(ans,(maxx-minn)/2.0);
        }
    }
    printf("%.1lf\n",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值