51nod-1319 跳跃游戏

思路:利用三角形三边关系 a+b>c,a-b<c将a[n]往后循环一遍,将x变为正数,预处理出a[2*n]的前缀和sum[2*n]

若x>=sum[n],则直接ans+=n*(x.sum[n]); x%=sum[n]; 相当于机器人一直沿x轴跳跃将x缩小到sum[n]内,在遍历前缀和1-->n,当x<=sum[i]时,表示 a+b=sum[i]>x,可构成三角形达到x处,(这里不必担心a-b<x,因为这里的x实际上是大于sum[n]的)ans+=i,退出循环。

若x<sum[n]并且x!=0, 遍历前缀和1-->2n,那么在a+b=sum[i]时还要考虑a-b<x,因此可以考虑选取a[1->i]中最长的为Max当做三角形的斜边,那么只要 sum[i]>=x并且sum[i]-Max+x>=Max时 就能够到达x处(=为一条直线的情况),ans=i.

Code:

#include<iostream>
using namespace std;
typedef long long LL;

const int MAX_N=105;
int n,x,T;
LL a[MAX_N],sum[MAX_N];

int main()
{
	ios::sync_with_stdio(false);
	cin>>T;
	while(T--){
		cin>>x>>n;
		x=max(x,-x);
		for(int i=1;i<=n;++i)
		{
			cin>>a[i];
			a[i+n]=a[i];
		}
		for(int i=1;i<=2*n;++i)
			sum[i]=sum[i-1]+a[i];
		int ans=0;
		if(x>=sum[n]){
			ans+=n*(x/sum[n]);
			x%=sum[n];
			for(int i=1;i<=n&&x>0;++i)
				if(x<=sum[i]){
					ans+=i;	break;
				}
		}else if(x){
			LL Max=0;
			for(int i=1;i<=2*n;++i)
			{
				Max=max(Max,a[i]);
				if(sum[i]>=x&&sum[i]-Max+x>=Max){
					ans=i;	break;
				}
			}
		}
		cout<<ans<<endl;
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/81486614