洛谷 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_Nw1​,w2​,⋯,wN​ 。保证 \{w_i\}{wi​} 为递增序列。

输出格式:

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

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

扫描二维码关注公众号,回复: 3541224 查看本文章

输入输出样例

输入样例#1: 复制

6 1 3
3

输出样例#1: 复制

YES
1 2 0

输入样例#2: 复制

6 2 2
2 4

输出样例#2: 复制

YES
2 3 1 0

输入样例#3: 复制

5 2 3
2 3

输出样例#3: 复制

NO

说明

1 \le N,S \le 1000001≤N,S≤100000

0 \le M < N0≤M<N

1 \le w_i < N1≤wi​<N

#include "stdafx.h"
//ios::sync_with_stdio(false);
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<queue>
#include<stack>
#include<cstring>
#include<string>

using namespace std;
typedef long long LL;


int main() {
	ios::sync_with_stdio(false);
	int st[100010];
	stack<int>way;
	int n, m, s;//河的宽度 岩石的数量 跳跃下限;
	scanf_s("%d%d%d", &n, &m, &s);
	for (int i = 1; i <= m; i++)scanf_s("%d", &st[i]);
	st[0] = 0; st[m + 1] = n;
	if (st[1] < s) { printf("NO"); return 0; }
	if (n - st[m] < s) { printf("NO"); return 0; }
	for (int i = 3; i <= m; i++) {
		if (st[i] - st[i - 2] < s) { printf("NO"); return 0; }
	}//排除所有无解情况
/*每个点只扫描一次,因为每个点都要走到,所以从0到m+1的时候,满足条件的点直接输出,不满足条件的点放入栈中最后输出*/
	printf("YES\n");
	int on = 0, next = -1;
	while (next < m + 1) {
		next++;
		if (st[next] - st[on] < s) {
			way.push(next);
		}
		else {
			cout << next << " ";
			on = next;
		}
	}
	while (!way.empty()) {
		printf("%d ", way.top());
		way.pop();
	}
}

猜你喜欢

转载自blog.csdn.net/leo_10/article/details/81356886