Codeforces Round #598 (Div. 3) C题

Codeforces Round #598 (Div. 3)

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

You are standing at 0 and want to reach n+1 somehow. If you are standing at the position x, you can jump to any position in the range [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, you can jump only to the next position (if it belongs to the wooden platform). You can assume that cells 0 and n+1 belong to wooden platforms.

You want to know if it is possible to reach n+1 from 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, m=3, d=2 and c=[1,2,1], then one of the ways to reach 8 from 0 is follow:


题目写的真的绕,大概意思就是给你m个木板,每个木板的长度告诉你,问你怎么摆放可以使你过河,你每次可以跳1–d;

贪心的每次跳最大的距离d,看是否可以过河;还要考虑一种情况,就是你贪心的过程中要考虑是否能摆放下所有的木板,如果不能,就应该跳小于d的距离;

代码:

#include<bits/stdc++.h>
using namespace std;
int c[1010];
int a[1010];
int main(){
	int n,m,d;
	scanf("%d%d%d",&n,&m,&d);
	int sum=0;
	for(int i=1;i<=m;i++){
		scanf("%d",&c[i]);
		sum+=c[i];
	}
	int ans=0;
	for(int i=1;i<=m;i++){
		sum-=c[i];
		if(n-(ans+d+c[i]-1)>=sum){//木板剩余的长度小于剩余河的长度 
			ans+=d;
			a[ans]=i;//木板
			for(int j=1;j<c[i];j++){
				ans++;
				a[ans]=i;
			}
		}
		else{
			int g=1;
			for(int k=d-1;k>=1;k--){
				if(n-(ans+k+c[i]-1)>=sum){
					g=k;
					break;
				}
			}
			ans+=g;
			a[ans]=i;//木板
			for(int j=1;j<c[i];j++){
				ans++;
				a[ans]=i;
			}
		}
	}
	if(ans+d<n+1){
		cout<<"NO"<<endl;
	}
	else{
		cout<<"YES"<<endl;
		for(int i=1;i<=n;i++) cout<<a[i]<<" ";
		cout<<endl;
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值