1 条题解

  • 0
    @ 2025-8-24 22:03:15

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar FlierKing
    **

    搬运于2025-08-24 22:03:15,当前版本为作者最后更新于2018-07-14 23:28:03,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    首先我们考虑最靠近开头和最靠近结尾的两块岩石,如果他们离开头/结尾的距离小于 SS,那么这块岩石将不可能被跳到,从而导致无解。

    对于三个连续的岩石 i,i+1,i+2i,i+1,i+2,如果wi+2wi<Sw_{i+2}-w_i<S ,由于我们只能来回一次,且每次跳到其中的一个石头上时必然不可能跳到另一个石头上,所以这种情况也会导致无解。

    那么有解时我们只需要贪心地能跳就选择一个距离不小于 SS 的且最近的跳就可以了。

    时间复杂度 O(N)O(N)

    #include <bits/stdc++.h>
    #define ll long long
    #define MAXN 100005
    using namespace std;
        int n,m,s,p,cnt;
        int a[MAXN],f[MAXN];
        bool u[MAXN];
    int inline read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int main()
    {
        n=read(),m=read(),s=read();
        for (int i=1;i<=m;i++)
            a[i]=read();
        sort(a+1,a+m+1);
        a[0]=0,a[m+1]=n;
        for (int i=1;i<=m+1;i++)
            if (a[i]-p>=s)
            {
                f[++cnt]=i;
                p=a[i];
                u[i]=true;
            }
        if (p!=a[m+1])
        {
            puts("NO");
            return 0;
        }
        for (int i=m;i>=0;i--)
            if (!u[i]&&p-a[i]>=s)
            {
                f[++cnt]=i;
                p=a[i];
                u[i]=true;
            }
        if (cnt<m+2)
            puts("NO");
        else
        {
            puts("YES");
            for (int i=1;i<=m+2;i++)
                printf("%d%c",f[i],i==m+2?'\n':' ');
        } 
        return 0;
    }
    
    • 1

    信息

    ID
    3647
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者