Potions And c++读取二维字符数组

8 篇文章 0 订阅
1 篇文章 0 订阅
This is the hard version of the problem. The only difference is that in this version n≤200000. You can make hacks only if both versions of the problem are solved.

There are n potions in a line, with potion 1 on the far left and potion n on the far right. Each potion will increase your health by ai when drunk. ai can be negative, meaning that potion will decrease will health.

You start with 0 health and you will walk from left to right, from first potion to the last one. At each potion, you may choose to drink it or ignore it. You must ensure that your health is always non-negative.

What is the largest number of potions you can drink?

input:
The first line contains a single integer n (1≤n≤200000) — the number of potions.

The next line contains n integers a1, a2, ... ,an (109≤ai≤109) which represent the change in health after drinking that potion.

output:
Output a single integer, the maximum number of potions you can drink without your health becoming negative.

题目意思就是说,给你n杯水,每个水可以是负或正,初始生命值为0,你要保证在自己生命值>0时,和尽可能多杯水,问:最多能和多少水?
乍一看像动态规划,其实不是,用的是贪心,我们尽可能的喝水,如果喝了后生命值为负,我们就吐出我们喝过的最小的水,再继续前行。(为什么吐出喝过最小的水,我们的生命值就一定>=0呢?假设我们喝了第i瓶水后生命值<0,那么我们将这瓶水吐出就一定可以让自己的生命值>=0,如果还有比这杯水更小的水,那么吐出后我们的生命值必>0);还有就是范围相对较大,可能溢出,用long存储一下当前的生命值;数组长度较大,想快速找到我们喝过的最小水,可以用优先队列,就是堆。

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class demo1 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n + 1];
        for(int i = 1; i <= n; i++) arr[i] = sc.nextInt();

        PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });

        long sum = 0, counter = 0;
        for (int i = 1; i <= n; i++) {
            sum += arr[i];
            pq.add(arr[i]);
            counter ++;
            if(sum < 0) {
                sum -= pq.poll();
                counter --;
            }
        }

        System.out.println(counter);
    }
}

在这里插入图片描述

想明白就不难了,但是难想。还得多做题吧

c++读取二位字符数组:
我们采取的是一个字符一个字符的读,当然用cin >> s[i]也可以;一个字符一个字符读用scanf不行,用cin行:
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
cin >> t[i][j];
}
}

学校的比赛更偏向脑筋急转弯,就是多做题吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值