码迷,mamicode.com
首页 > 其他好文 > 详细

P4753 River Jumping

时间:2018-07-15 23:50:24      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:mpi   处理   mit   思路   def   ret   algorithm   lse   两种   

P4753 River Jumping

题目描述
有一条宽度为 NN 的河上,小D位于坐标为 00 的河岸上,他想到达坐标为 NN 的河岸上后再回到坐标为 00 的位置。在到达坐标为 NN 的河岸之前小D只能向坐标更大的位置跳跃,在到达坐标为 NN 的河岸之后小D只能向坐标更小的位置跳跃。在河的中间有 MM 个岩石,小D希望能跳到每个岩石上恰好一次。由于小D的跳跃能力太强,小D的跳跃长度有个下限 SS ,但没有上限。现在请你判断他是否能够完成他的目标。

输入输出格式
输入格式:
第一行输入两个整数 N,M,SN,M,S ,分别表示河的宽度,岩石的数量和跳跃长度的下限。

第二行输入 MM 个整数,分别表示 MM 个岩石的坐标 w_1,w_2,\cdots,w_Nw
1
? ,w
2
? ,?,w
N
? 。保证 {w_i}{w
i
? } 为递增序列。

输出格式:
如果小D可以完成他的目标,第一行输出YES,第二行输出 M+2M+2 个数,依次表示小D跳到的石头编号。特殊的,坐标为 00 的河岸编号为 00 ,坐标为 NN 的河岸标号为 M+1M+1 。如果有多种解法,允许输出任意一种。

如果小D不能完成他的目标,第一行输出NO。


每个点只可能有两种情况被跳到,要么去的时候,要么回的时候。因为腿力巨大,我们当然希望石子挨的越远越好。

这样就有了贪心的基本思路:在第一次去的时候尽量跳多的点,“尽可能为第二次跳删去多的点”

所以说纠正一些题解的讲法:这题不全是贪心,前一次跳为贪心,删去尽可能多的点,而第二次仅仅是一个判断,因为若是不满足条件,那么这个点再没有第三次机会被删去了

注意样例是把两岸当做点处理的

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
typedef long long LL;
using namespace std;
int RD(){
    int out = 0,flag = 1;char c = getchar();
    while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
    while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
    return flag * out;
    }
const int maxn = 100019;
int len, num, S;
int a[maxn];
bool vis[maxn];
int pre[maxn];
int s[maxn],top;
int main(){
    len = RD();num = RD();S = RD();
    for(int i = 1;i <= num;i++){a[i] = RD();}
    a[0] = 0, a[num + 1] = len;
    int i = 1,now = 0,tot = num, last = 0;
    while(i <= num){
        if(now + S <= a[i])tot--, pre[i] = last, last = i, now = a[i], vis[i] = 1;
        i++;
        }
    if(a[last] + S > len){printf("NO\n");return 0;}
    pre[num + 1] = last;
    i = num, now = len, last = num + 1;
    while(i >= 1){
        if(now - S >= a[i] && !vis[i])tot--, pre[i] = last, last = i, now = a[i], vis[i] = 1;
        i--;
        }
    if(a[last] - S < 0){printf("NO\n");return 0;}
    if(!tot){
        printf("YES\n");
        while(pre[last] != 0)s[++top] = last, last = pre[last];
        s[++top] = last;
        while(top)printf("%d ", s[top--]);
        printf("0\n");
        }
    else printf("NO\n");
    return 0;
    }

P4753 River Jumping

标签:mpi   处理   mit   思路   def   ret   algorithm   lse   两种   

原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9315614.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!