Slimming Plan(模拟)

题目描述
Chokudai loves eating so much. However, his doctor Akensho told him that he was overweight, so he finally decided to lose his weight.

Chokudai made a slimming plan of a D-day cycle. It is represented by D integers w0,…,wD−1. His weight is S on the 0-th day of the plan and he aims to reduce it to T (S>T). If his weight on the i-th day of the plan is x, it will be x+wi%D on the (i+1)-th day. Note that i%D is the remainder obtained by dividing i by D. If his weight successfully gets less than or equal to T, he will stop slimming immediately.

If his slimming plan takes too many days or even does not end forever, he should reconsider it.

Determine whether it ends or not, and report how many days it takes if it ends.

输入
The input consists of a single test case formatted as follows.

S T D
w0…wD−1
The first line consists of three integers S, T, D (1≤S,T,D≤100,000,S>T). The second line consists of D integers w0,…,wD−1(−100,000≤wi≤100,000 for each i).

输出
If Chokudai’s slimming plan ends on the d-th day, print d in one line. If it never ends, print −1.

样例输入
65 60 3
-2 3 -4
样例输出
4

看着挺简单一个题,快坑死我了,wa了十几次出不来。。吐血。最后几分钟的时候过了,,,真是惊险刺激

题意:xxx想减肥,一开始他的体重是s,想减到t,他有个d天的减肥计划,每天对应一个w[i],即从w[0],w[1],w[2]…w[d-1],若他第i天的体重是x,那么第i+1天的体重是x+w[i%d]。(刚开始没看到i%d在下标上。。。以为是w[i]%d。。wa了很多次)
求最少多少天能减到t,若永远减不到,输出-1。
思路:
1.先想怎么特判(什么情况下输出-1),求出每一轮d的总和sum,若它大于等于0,则他永远减不到。其中有个特殊情况就是他在第一轮的中途某一天减到了t,再特判一下这种情况就好。
2.求出每一轮最多能减的值mint(最小前缀和),while循环进行的轮数,直到进行到某一轮,s+轮数*sum+mint<=t,再对这一轮进行遍历,找到最小的那天,输出。

AC代码:

#include<iostream>
using namespace std;
typedef long long ll;
#define N 100005
#define inf 1e15     //N*N是超Int的,所以初始化的时候要给一个很大的数
int a[N];
int main()
{
	ll s,t,d,ans=0,mint=inf,sum=0,tem;    //这些数都要用long long,原因如上(刚开始没想到qaq)
	cin>>s>>t>>d;            //不知道那个oj能不能用lld输入,干脆直接用cin
	for(int i=0;i<d;i++)
	{
		scanf("%d",&a[i]);
		sum+=a[i];        
		if(sum<mint)           //sum和mint都求出来
			mint=sum;
	}
	tem=s;
	for(int i=0;i<d;i++)        //特判一下是否在第一轮就减到目标值
	{
		tem+=a[i];
		if(tem<=t)
		{
			cout<<i+1<<endl;
			return 0;
		}
	}
	if(sum>=0)       //若在一轮中途减不到目标值,而一轮总和为非负值,那么永远减不到目标值
	{
		cout<<-1<<endl;
		return 0;
	}
	int x=1;           //x代表进行的轮数
	while(1)
	{
		if(s+sum*x+mint<=t)     //若在某一轮的下一轮能减到
		{
			tem=0;
			for(int i=0;i<d;i++)     //找到最快达到目标值的那天,输出天数
			{
				tem+=a[i];
				if(s+sum*x+tem<=t)
				{
					ans=x*d+i+1;break;
				}
			}
			cout<<ans<<endl;
			return 0;
		}
		x++;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值