51Nod 试题泛做1

发布时间 2023-06-22 09:47:27作者: Code_AC

A-排船的问题

很显然,这个数据范围用二分来找这个最长的最短是OK的,
然后我们就判断一下二分到的东西,用一个贪心,就是尽可能将每一个往左边放,但不能与船重叠,也不能超过我们二分到的最长的绳的长度,因为要尽可能给后面留出空间,让后面的绳的长度不超过我们二分到的长度。
然后如果最后极限的方法仍飞出了港口,那自然就是不行的,就继续二分。

可以这样理解。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=5e4+5;

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

int n,x,m;
int p[MAXN];

inline bool check(int pos)
{
    int head=0,tail=0;
    for(int i=1;i<=n;i++)
    {
        head=tail;
        if(head+x>p[i]+pos) return false;
        tail=max(head+2*x,p[i]-pos+x);
    }
    if(tail>m) return false;
    return true;
}

int main()
{
    n=read(),x=read(),m=read();
    for(int i=1;i<=n;i++) p[i]=read();
    if((x*2*n)>m) {printf("-1\n");return 0;}
    int l=0,r=m-1,ans;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(check(mid))ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

B-稳定桌

点击查看代码