CF1256C Platforms Jumping 题解

文章目录

  • [CF1256C Platforms Jumping](https://www.luogu.com.cn/problem/CF1256C) 题解
    • 题目描述
    • 输入格式
    • 输出格式
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 样例 #2
      • 样例输入 #2
      • 样例输出 #2
    • 样例 #3
      • 样例输入 #3
      • 样例输出 #3
    • 提示
    • 算法:贪心
    • 代码:

CF1256C Platforms Jumping 题解

题目描述

有一条宽度为 n n n 的河。河的左岸编号为 0 0 0,右岸编号为 n + 1 n + 1 n+1。河流上还有 m m m 个木制平台,第 i i i 个平台的长度为 c i ci ci(所以说第i个平台占据河流的 c i ci ci 个连续位置)。保证平台长度的总和不超过 n n n

你正站在 0 0 0(左岸),并且想到达右岸即 n + 1 n + 1 n+1 的位置。如果您站在位置 x x x,则可以跳到 [ x + 1 ; x + d ] [x + 1; x + d] [x+1;x+d] 范围内的任何位置。但是, 你只能跳到木质平台上( 即不能下水_)。例如,如果 d = 1 d = 1 d=1,则只能跳到下一个位置(如果这个位置上有木制平台)。您可以假设单元格 0 0 0 n + 1 n + 1 n+1 属于木制平台。

您可以将任意平台向左或向右移动任意次数(也可以不移动),只要它们彼此不重叠(但两个平台可以挨在一起)。也就是说你不能更改平台的相对顺序。

请注意,你应该先移动平台再跳跃(一旦你出发后,你就不能再移动平台了)。

例如,如果 n = 7 n = 7 n=7 m = 3 m = 3 m=3 d = 2 d = 2 d=2 c = [ 1 , 2 , 1 ] c = [1,2,1] c=[1,2,1],这就是从左岸跳到右岸的方法之一:

CF1256C Platforms Jumping 题解_第1张图片

输入格式

输入的第一行包含三个整数 n n n m m m d d d 1 ≤ n , m , d ≤ 1000 , m ≤ n 1≤n,m,d≤1000,m≤n 1nmd1000mn)

输入的第二行包含m个整数 c 1 , c 2 , … , c m ( 1 ≤ c i ≤ n c_1,c_2,\dots,c_m(1 \le ci \le n c1c2cm1cin ∑ i = 1 m c i ≤ n \sum_{i=1}^mci \le n i=1mcin 【这里打的和原题面格式不太一样,就是说木平台的长度和不大于河宽】 ),其中 c i c_i ci 是第 i i i 个平台的长度。

输出格式

如果不可能从 0 0 0 达到 n + 1 n + 1 n+1,则在第一行中输出"NO"。否则,在第一行中打印“YES”,在第二行中输出长度为n的数组 输出河流的序列(不输出单元格 0 0 0 和单元格 n + 1 n + 1 n+1)。

如果河流单元格 i i i 不属于任何平台,输出 0 0 0。否则,它应该是等于平台的编号(平台编号是从 1 1 1 m m m 输入的顺序)。

题目描述

There is a river of width n n n . The left bank of the river is cell 0 0 0 and the right bank is cell n + 1 n + 1 n+1 (more formally, the river can be represented as a sequence of n + 2 n + 2 n+2 cells numbered from 0 0 0 to n + 1 n + 1 n+1 ). There are also m m m wooden platforms on a river, the i i i -th platform has length c i c_i ci (so the i i i -th platform takes c i c_i ci consecutive cells of the river). It is guaranteed that the sum of lengths of platforms does not exceed n n n .

You are standing at 0 0 0 and want to reach n + 1 n+1 n+1 somehow. If you are standing at the position x x x , you can jump to any position in the range [ x + 1 ; x + d ] [x + 1; x + d] [x+1;x+d] . However you don’t really like the water so you can jump only to such cells that belong to some wooden platform. For example, if d = 1 d=1 d=1 , you can jump only to the next position (if it belongs to the wooden platform). You can assume that cells 0 0 0 and n + 1 n+1 n+1 belong to wooden platforms.

You want to know if it is possible to reach n + 1 n+1 n+1 from 0 0 0 if you can move any platform to the left or to the right arbitrary number of times (possibly, zero) as long as they do not intersect each other (but two platforms can touch each other). It also means that you cannot change the relative order of platforms.

Note that you should move platforms until you start jumping (in other words, you first move the platforms and then start jumping).

For example, if n = 7 n=7 n=7 , m = 3 m=3 m=3 , d = 2 d=2 d=2 and c = [ 1 , 2 , 1 ] c = [1, 2, 1] c=[1,2,1] , then one of the ways to reach 8 8 8 from 0 0 0 is follow:

CF1256C Platforms Jumping 题解_第2张图片The first example: n = 7 n=7 n=7 .

输入格式

The first line of the input contains three integers n n n , m m m and d d d ( 1 ≤ n , m , d ≤ 1000 , m ≤ n 1 \le n, m, d \le 1000, m \le n 1n,m,d1000,mn ) — the width of the river, the number of platforms and the maximum distance of your jump, correspondingly.

The second line of the input contains m m m integers c 1 , c 2 , … , c m c_1, c_2, \dots, c_m c1,c2,,cm ( 1 ≤ c i ≤ n , ∑ i = 1 m c i ≤ n 1 \le c_i \le n, \sum\limits_{i=1}^{m} c_i \le n 1cin,i=1mcin ), where c i c_i ci is the length of the i i i -th platform.

输出格式

If it is impossible to reach n + 1 n+1 n+1 from 0 0 0 , print NO in the first line. Otherwise, print YES in the first line and the array a a a of length n n n in the second line — the sequence of river cells (excluding cell 0 0 0 and cell n + 1 n + 1 n+1 ).

If the cell i i i does not belong to any platform, a i a_i ai should be 0 0 0 . Otherwise, it should be equal to the index of the platform ( 1 1 1 -indexed, platforms are numbered from 1 1 1 to m m m in order of input) to which the cell i i i belongs.

Note that all a i a_i ai equal to 1 1 1 should form a contiguous subsegment of the array a a a of length c 1 c_1 c1 , all a i a_i ai equal to 2 2 2 should form a contiguous subsegment of the array a a a of length c 2 c_2 c2 , …, all a i a_i ai equal to m m m should form a contiguous subsegment of the array a a a of length c m c_m cm . The leftmost position of 2 2 2 in a a a should be greater than the rightmost position of 1 1 1 , the leftmost position of 3 3 3 in a a a should be greater than the rightmost position of 2 2 2 , …, the leftmost position of m m m in a a a should be greater than the rightmost position of m − 1 m-1 m1 .

See example outputs for better understanding.

样例 #1

样例输入 #1

7 3 2
1 2 1

样例输出 #1

YES
0 1 0 2 2 0 3

样例 #2

样例输入 #2

10 1 11
1

样例输出 #2

YES
0 0 0 0 0 0 0 0 0 1

样例 #3

样例输入 #3

10 1 5
2

样例输出 #3

YES
0 0 0 0 1 1 0 0 0 0

提示

Consider the first example: the answer is [ 0 , 1 , 0 , 2 , 2 , 0 , 3 ] [0, 1, 0, 2, 2, 0, 3] [0,1,0,2,2,0,3] . The sequence of jumps you perform is 0 → 2 → 4 → 5 → 7 → 8 0 \rightarrow 2 \rightarrow 4 \rightarrow 5 \rightarrow 7 \rightarrow 8 024578 .

Consider the second example: it does not matter how to place the platform because you always can jump from 0 0 0 to 11 11 11 .

Consider the third example: the answer is [ 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 ] [0, 0, 0, 0, 1, 1, 0, 0, 0, 0] [0,0,0,0,1,1,0,0,0,0] . The sequence of jumps you perform is 0 → 5 → 6 → 11 0 \rightarrow 5 \rightarrow 6 \rightarrow 11 05611 .

算法:贪心

先贪心地将跳过路段最大化,跳出边界后再一个个紧挨着放即可。\

具体见代码~

代码:

#include
using namespace std;
#define ll long long
const ll N=1010;
ll n,m,d,ans,c[N],sum,i,t,p=1;
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>m>>d;d--;
	for(i=1;i<=m;i++) cin>>c[i],sum+=c[i];	
	if(sum+(m+1)*d<n){
		cout<<"NO";
		return 0;
	}else cout<<"YES\n";
	t=n-sum;i=0;
	while(i<=n){
		for(int j=1;j<=d&&t;j++){
			cout<<"0 ";
			i++,t--;
		}
		if((++i)>n||p>m) return 0;
		for(int j=i;j<c[p]+i;j++) cout<<p<<" ";
		p++;
	}
	return 0;
}

你可能感兴趣的:(题解,c++,算法,贪心算法)