51nod1243

链接:点击打开链接

题意:一个码头中有N艘船和N个木桩,船的长度为2*X,码头的宽度为M,N个木桩的位置(相对码头左岸的位置)会在数据中给出。船和船之间不能重叠,即每艘船的船头不能超过上一艘船的船尾,当然也不能超出码头的两岸。船和木桩之间用绳子连接,并且1个木桩只能栓1条船,绳子的一头拴在木桩上,另一头拴在船的中间。而船中间到木桩的距离,就是所需的绳子的长度。由你根据给出的条件,排列船的位置,使得所用到的最长的绳子最短。输出这个最短的长度,如果码头排不下所有船则输出-1。

代码:

#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
int N,X,M;
int p[50005];
int judge(int d){
    int i,j,st,en,sum;
    st=2*X,sum=0;                       //st的意义是当前这条船的船尾最靠左能放的位置
    for(i=0;i<N;i++){
    if(abs(st-p[i]-X)<=d){              //符合每条绳子的长度都小于等于d时,第i条船一定
        st+=2*X;                        //在以第i条木桩为中点的一条线段内,因此当st已经
        continue;                       //在区间内时直接推出下一个st,如果小于左边界,则
    }                                   //将st赋成左边界,否则return 0,因为在边界内的话
    else{                               //是不会进行到这一步的,所以直接return 0
        if(p[i]-d+X>st)
        st=p[i]-d+X;
        else
        return 0;
        st+=2*X;
    }
    }
    if(st-2*X>M)
    return 0;
    return 1;
}
int main(){
    int i,j,l,r,mid,ans;
    while(scanf("%d%d%d",&N,&X,&M)!=EOF){
        for(i=0;i<N;i++)
        scanf("%d",&p[i]);
        if(N*2*X>M){
            puts("-1");
            continue;
        }
        l=0;r=M;                        //二分绳子长度    
        while(r>=l){
            mid=(l+r)/2;
            if(judge(mid)){
                ans=mid;
                r=mid-1;
            }
            else
            l=mid+1;
        }
        printf("%d\n",ans);
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值