Codeforces Round #547 (Div. 3) E. Superhero Battle

E. Superhero Battle

A superhero fights with a monster. The battle consists of rounds, each of which lasts exactly ?n minutes. After a round ends, the next round starts immediately. This is repeated over and over again.

Each round has the same scenario. It is described by a sequence of ?n numbers: ?1,?2,,??d1,d2,…,dn (106??106−106≤di≤106). The ?i-th element means that monster's hp (hit points) changes by the value ??di during the ?i-th minute of each round. Formally, if before the ?i-th minute of a round the monster's hp is h, then after the ?i-th minute it changes to :=+??h:=h+di.

The monster's initial hp is ?H. It means that before the battle the monster has ?H hit points. Print the first minute after which the monster dies. The monster dies if its hp is less than or equal to 00. Print -1 if the battle continues infinitely.

Input

The first line contains two integers ?H and ?n (1?10121≤H≤1012, 1?21051≤n≤2⋅105). The second line contains the sequence of integers ?1,?2,,??d1,d2,…,dn (106??106−106≤di≤106), where ??di is the value to change monster's hp in the ?i-th minute of a round.

Output

Print -1 if the superhero can't kill the monster and the battle will last infinitely. Otherwise, print the positive integer ?ksuch that ?k is the first minute after which the monster is dead.

Examples
input
Copy
1000 6
-100 -200 -300 125 77 -4
output
Copy
9
input
Copy
1000000000000 5
-1 0 0 0 0
output
Copy
4999999999996
input
Copy
10 4
-3 -6 5 4
output
Copy
-1

题意:给定一个怪的hp,和一轮的攻击次数n;然后给n次攻击的伤害(有正有负),如果一轮内怪不死会一直按顺序重复这n次的攻击,问攻击到多少下怪会死。

思路:二分答案,但是在二分之前要特判一下怪打不死之类的情况;用一个前缀和记录一轮中直至目前造成的伤害和,二分内部每次判这一轮能不能把怪打死,如果能,更新一下攻击次数。

代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define ll long long
#define lowbit(x) (x&(-x))
#define PI acos(-1)
#define ms(x,y) memset(x, y, sizeof(x))
using namespace std;

const int maxn = 2e5+7;
ll arr[maxn];
ll pre[maxn];

int main()
{
    ll hp, tot = 0, maxx = 0;
    int n;
    scanf("%lld%d", &hp, &n);
    for(int i=0;i<n;i++)
    {
        scanf("%lld", arr+i);
        tot += arr[i];
        pre[i] = i ? pre[i-1] + arr[i] : arr[i];
        if(-pre[i] > maxx) maxx = -pre[i];
    }
    
    if(maxx < hp && tot >= 0)
    {
        printf("-1\n"); // never die
        return 0;
    }
    else if(maxx >= hp && tot >= 0) // die on round 1
    {
        for(int i=0;i<n;i++)
            if(-pre[i] >= hp)
            {
                printf("%d\n", i+1); break;
            }
        return 0;
    }
    else // must die
    {
        tot = -tot;
        ll l = 1, r = hp/tot + (hp%tot != 0) + 1, mid;
        ll minn = r;
        ll ans = 0;
        while(l < r)
        {
            mid = l + (r-l) / 2; // this round
            ll tp = hp - tot * (mid-1); // have deducted before
            if(maxx >= tp) // will die this round
            {
                ll tp_ans = ans;
                for(int i=0;i<n;i++)
                    if(-pre[i] >= tp)
                    {
                        tp_ans = i+1 + (mid-1)*n;
                        break;
                    }
                if(mid < minn)
                {
                    minn = mid;
                    ans = tp_ans;
                }
                r = mid;
            }
            else l = mid+1;
            
        }
        printf("%lld\n", ans);
    }
}

  

转载于:https://www.cnblogs.com/HazelNut/p/10578517.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值