蓝桥杯 Day8 java组 前缀和

对于一个长度为n的数组 a[0]∼a[n−1],它的前缀和 sum[i] 等于 a[0]∼a[i] 的和。例如:

  • sum[0] = a[0]
  • sum[1] = a[0] + a[1]
  • sum[2] = a[0] + a[1] + a[2]

        利用递推,只要计算 n 次,就能计算出所有的前缀和:sum[i] = sum[i-1] + a[i]。当然,我们也能用 sum[] 反推计算出 a[]:a[i] = sum[i] - sum[i-1]。

如果预先算出了前缀和,这时想知道 a[i]∼a[j] 的和,可以用sum[j]−sum[i−1]。 可以利用前缀和快速计算出数组中任意一个区间的和。本来复杂度为 O(n)的区间和计算,优化到了 O(1) 的前缀和计算。

第一题 灵能传输

 

样例输入

3
3
5 -2 3
4
0 0 0 0
3
1 2 3

样例输出

3
0
3

 

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner cinScanner = new Scanner(System.in);
        int T;
        T = cinScanner.nextInt();
        while (T != 0) {
            T--;
            long in0 = 0, inn = 0;
            long n;
            long s0, sn;
            n = cinScanner.nextLong();
            long[] a = new long[(int) n + 2];
            long[] s = new long[(int) n + 1];
            long[] vis = new long[(int) n + 2];
            long[] ans = new long[(int) n + 2];
            for (int i = 0; i < n; i++) {
                a[i] = cinScanner.nextLong();
                s[i + 1] = a[i];
                s[i + 1] += s[i];
            }
            s0 = s[0];
            sn = s[(int) n];
            if (s0 > sn) {
                long t = s0;
                s0 = sn;
                sn = t;
            }
            Arrays.sort(s);
            for (int i = 0; i <= (int) n; i++)
                if (s[i] == s0) {
                    in0 = i;
                    break;
                }
            for (int i = (int) n; i >= 0; i--)
                if (s[i] == sn) {
                    inn = i;
                    break;
                }
            int l = 0;
            int r = (int) n;
            for (int i = (int) in0; i >= 0; i -= 2) {
                ans[l++] = s[i];
                vis[i] = 1;
            }
            for (int i = (int) inn; i <= n; i += 2) {
                ans[r--] = s[i];
                vis[i] = 1;
            }
            for (int i = 0; i <= n; i++)
                if (vis[i] == 0)
                    ans[l++] = s[i];
            long res = 0;
            for (int i = 1; i <= n; i++)
                res = Math.max(Math.abs((ans[i] - ans[i - 1])), res);
            System.out.println(res);
        }
    }
}
  • 为什么s[0]不会改变?应该只有s[n]的值不会改变
  • 根本没有s[0]这种东西 有什么意义?
  • 为什么重叠区隔一个取一个数可以保证正确?

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值