luogu P4753 【River Jumping】

比赛来迟了,9:34过的这题,9:30比赛停了TT

算法:

贪心

思路:

将终点变为最后一块石头,起点变为第一块石头,第一轮先将所有能跳的石头跳过,跳到终点, vis[a[i]] 打标记,表示此石头已经跳过,并记录跳过的下标,第二轮往回跳,已经跳过的石头不能再跳,并记录跳过的下标。最后看所有点是否跳过,没有,就输出NO,否则输出YES,并输出记录跳过的下标的数组。

代码:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int a[100005],v[100005],dl[100005];
int main()
{
    int n,m,s,i,j,k=0;
    cin>>n>>m>>s;
    for (i=1;i<=m;i++)
    {
        scanf("%d",&a[i]);
    }
    if (n<s)//若河宽小于跳跃下限,直接“NO”
    {
        cout<<"NO"<<endl;
        return 0;
    }
    int qs=0;
    a[m+1]=n;
    a[0]=0;
    for (i=1;i<=m+1;i++)
    {
        if (a[i]-qs>=s)
        {
            qs=a[i];
            v[a[i]]=1;
            dl[++k]=i;
        }
    }
    int zz=n;
    for (i=m;i>=0;i--)
    {
        if (zz-a[i]>=s&&v[a[i]]==0)
        {
            zz=a[i];
            v[a[i]]=1;
            dl[++k]=i;
        }
    }
    for (i=0;i<=m+1;i++)
    if (v[a[i]]==0)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for (i=1;i<=k;i++)
    {
        cout<<dl[i]<<" ";
    }
    return 0;
} 

 

 
posted @ 2018-08-15 15:11  C919  阅读(119)  评论(0)    收藏  举报