问题 B: Slimming Plan
时间限制: 1 Sec 内存限制: 128 MB
提交: 805 解决: 73
[提交] [状态] [命题人:admin]
题目描述
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
题目有很多种情况:
1.在第一轮的时候,前边的数可以把S直接减到T,但后边的数是比较大的正数,这种情况下,就直接模拟第一轮就行
2.还有就是,第一个不满足,所以的可能加起来sum>=0 这种情况下,无论进行多少轮都不可能减
3.第三种就是sum是负数,所以可以经过若干轮之后不S减到T,这样的话就是要用while不断的模拟
#include<iostream>
using namespace std;
typedef long long ll;
#define N 100005
#define inf 1e15
int a[N];
int main(){
ll s,t,d,ans=0,mint=inf,sum=0,tem;
scanf("%lld%lld%lld",&s,&t,&d);
for(int i=0;i<d;i++){
scanf("%d",&a[i]);
sum+=a[i];
if(sum<mint)
mint=sum;//最小的那种可能
}
tem=s;
for(int i=0;i<d;i++){//看看是不是在第一轮的时候,前边几天就可以满足条件
tem+=a[i];
if(tem<=t){
printf("%d\n",i+1);
return 0;
}
}
if(sum>=0){//第一轮不满足,这种情况更不可能减
printf("-1\n");
return 0;
}
int count=1;
while(1){
if(s+sum*count+mint<=t){//看看在最小的可能下是否满足条件
tem=0;
for(int i=0;i<d;i++){
tem+=a[i];
if(s+sum*count+tem<=t){
ans=count*d+i+1;//满足条件,退出
break;
}
}
printf("%lld\n",ans);
return 0;
}
count++;
}
return 0;
}