200字
连续数组和
2025-12-06
2025-12-06

题目

给定一个含有N个正整数的数组, 求出有多少个连续区间(包括单个正整数), 它们的和大于等于x。

输入描述

第一行两个整数N x(0 < N <= 100000, 0 <= x <= 10000000)

第二行有N个正整数(每个正整数小于等于100)。

输出描述

输出一个整数,表示所求的个数。

注意:此题对效率有要求,暴力解法通过率不高,请考虑高效的实现方式。

示例1 输入输出示例仅供调试,后台判题数据一般不包含示例

输入

3 7

3 4 7

输出

4

样例解释

第一行的3表示第二行数组输入3个数,第一行的7是比较数,用于判断连续数组是否大于该数;

组合为 3 + 4; 3 + 4 + 7; 4 + 7; 7; 都大于等于指定的7;所以共四组。

示例2 输入输出示例仅供调试,后台判题数据一般不包含示例

10 10000

1 2 3 4 5 6 7 8 9 10

样例解释

所有元素的和小于10000,所以返回0。

import sys

def main():
    N, x = map(int, sys.stdin.readline().split())  # N: 数组长度, x: 目标和阈值
    arr = list(map(int, sys.stdin.readline().split()))  # arr: 输入的正整数数组

    left = 0  # 滑动窗口左边界(包含)
    cur_sum = 0  # 当前窗口[left, right]的和
    count = 0  # 满足条件的区间个数

    for right in range(N):  # right: 滑动窗口右边界(包含)
        cur_sum += arr[right]  # 扩大窗口,加入arr[right]

        # 核心:当窗口和满足条件时
        while cur_sum >= x:
            # 统计:以left为起点,right为最小右端点,所有更大的右端点都满足
            count += N - right
            # 缩小窗口,移动左边界
            cur_sum -= arr[left]
            left += 1
    print(count)
if __name__ == '__main__':
    main()

注意这里有一个很巧妙的算法实现

count += N - right

这是本题的核心优化

  • 当找到第一个满足条件的右端点right

  • 由于数组元素都是正数,所以right右边的所有位置作为右端点也都满足

  • 因此可以直接加上N - right个区间,避免了逐个检查

滑动窗口模板

def sliding_window_template(nums, target):
    left = 0          # 窗口左边界
    cur_sum = 0       # 当前窗口和
    result = 0        # 结果(可能是计数、最小长度等)
    
    # 外层循环:移动右边界
    for right in range(len(nums)):
        # 1. 扩大窗口:加入nums[right]
        cur_sum += nums[right]
        
        # 2. 内层循环:当窗口满足条件时
        while 满足某种条件(cur_sum, target):
            # 3. 更新结果(根据具体问题)
            result = update_result(result, left, right)
            
            # 4. 缩小窗口:移动左边界
            cur_sum -= nums[left]
            left += 1
    
    return result

连续数组和
作者
Shisuiyi
发表于
2025-12-06
License
CC BY-NC-SA 4.0

评论