Codeforces Round #822 (Div. 2) D. Slime Escape

 input:

6
7 4
-1 -2 -3 6 -2 -3 -1
3 1
232 -500 -700
7 4
-1 -2 -4 6 -2 -4 -1
8 4
-100 10 -7 6 -2 -3 6 -10
8 2
-999 0 -2 3 4 5 6 7
7 3
7 3 3 4 2 1 1

output:

YES
YES
NO
YES
NO
YES

题目大意:给我们一个长度为n的数组,并给我们一个数字k,表示我们起始位于a[k]位置,也就是我们初始的健康值为a[k],题目保证a[k]>=0,我们可以向左向右走,但是当走到一个位置的时候我们的健康值要加上当前位置x上的值a[x],注意每个位置上的值只有第一次经过的时候才会加入健康值,当第二次经过的时候就不用加了,问我们能否在健康值始终大于等于0的条件下走出这个数组,也就是说走到a[1]或者是a[n]位置。

解题思路:贪心。先选定一份方向,假设是先向左走,一直向左走直到不能继续走为止,走的过程中记录健康值取到最大的位置,将我们向左走的终点暂定为取到最大值的位置,然后再向右走,同样是走到不能走为止,记录在向左走取到的最大值的基础上,该过程中取到的最大值,然后以取到最大值的位置为基础再向左走,如此循环往复,如果最后能走到端点处就输出YES,否则如果左右两边都无法进行扩展了,级输出NO。

上代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=2e5+10;
long long t,n,k,a[N];
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>k;
		for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
		if((k==1)||(k==n))
		{
			cout<<"YES"<<endl;
			continue;
		}
		long long ans=a[k];
		long long l=k,r=k;
		bool flag=false;
		while(l>=1&&r<=n)
		{
			long long ansl=ans;
			long long posl=l,maxvl=ans;
			for(int i=l-1;i>=1;i--)
			{
				if(ansl+a[i]>=maxvl)
				{
					maxvl=ansl+a[i];
					posl=i;
				}
				ansl+=a[i];
				if(ansl<0)
				break;
				if(i==1&&ansl>=0)
				flag=true;
			}
			if(flag)
			break;
			long long posr=r,maxvr=maxvl;
			long long ansr=maxvl;
			for(int i=r+1;i<=n;i++)
			{
				if(ansr+a[i]>maxvr)
				{
					maxvr=ansr+a[i];
					posr=i;
				}
				ansr+=a[i];
				if(ansr<0)
				break;
				if(i==n&&ansr>=0)
				flag=true;
			}
			if(flag)
			break;
			ans=maxvr;
			if(l==posl&&r==posr)
			break;
			l=posl;
			r=posr;
		}
		if(flag)
		cout<<"YES"<<endl;
		else
		cout<<"NO"<<endl;
	}	
	return 0;
} 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值