这题其实不难,为啥放在cf div2的E呢?
下文中,每个round对怪物造成的净伤害为sum,一个round中对这个怪物的最大伤害为mx,均为负数
这题主要是有个坑点:可能在一个round中会有一个点,它大于整个round结束之后对怪物造成的净伤害。所以,我们需要找出一个round中最大的伤害的点mx。
比如,样例1中,最大伤害点是-100-200-300=600。
因此,我们可以这样思考:如果一个round开始之前,这个怪物的血量h<=mx,那它就会死在这个round,而前面我们需要做的,就是把这个怪物的血线压到mx以下,因此,前面造成的伤害为h+mx(mx为伤害,为负数),而这个伤害只能由净伤害造成,因此,需要的round数为need_r=ceil((h+mx)/(-sum)),也就是说,need_r+1轮内这个怪物必死,然后,再遍历di,找出这个怪物会死在哪个点i,就可以得到答案为need_r*n+i.
注意特判情况,也就是在mx和sum均小于怪物血量h的时候,这个怪物无法被杀死。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
template<typename T>
void read(T&x){
char ch=getchar();
ll f=1;
while(!isdigit(ch)){
if(ch=='-')f*=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
template<typename T>
void write(T x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
//===========================================================
#define int ll
ll h,n;
int d[maxn];
int solve(){
int mx=0;
for(int i=1;i<=n;i++){
d[i]+=d[i-1];
if(h+d[i]<=0)return i;
mx=min(mx,d[i]);
}
if(d[n]>=0)return -1;
int need=h+mx;
//cerr<<"*"<<need<<endl;
//cerr<<d[n]<<endl;
int need_r=ceil(1.0*need/(-d[n]));
//cerr<<need_r<<" "<<need_r*d[n]<<endl;
h+=need_r*d[n];
for(int i=1;i<=n;i++){
if(h+d[i]<=0){
return need_r*n+i;
}
}
exit(1);
}
signed main(){
//freopen("in.txt","r",stdin);
read(h),read(n);
for(int i=1;i<=n;i++)read(d[i]);
write(solve());
return 0;
}
京公网安备 11010502036488号