题目描述


算法原理
这道题的核心在于利用滑动窗口来高效地寻找满足条件的子数组。我们不需要枚举所有可能的区间,而是通过两个指针动态维护一个窗口。
初始化时,定义左右指针 prev 和 cur 均指向数组起始位置,同时用一个变量 sum 记录当前窗口内的元素总和。逻辑主要分为两种情况:
当 sum 小于目标值 x 时,说明当前窗口还不够大,需要扩大右边界,即 cur 向右移动,并将新加入的元素累加到 sum 中。
一旦 sum 达到或超过 x,我们就找到了一个可行解。此时需要保存当前的左右边界信息。为了寻找更优解(通常是最短或特定条件下的区间),我们在满足条件的前提下,尝试收缩左边界:减去 arr[prev] 的值,并将 prev 右移。只要收缩后 sum 依然满足条件,就继续记录并收缩,直到不满足为止。
重复上述过程,直到右指针遍历完整个数组。
代码实现
下面是完整的 C++ 实现,注意处理输入输出格式以及索引转换(题目通常要求 1-based 索引)。
#include <iostream>
#include <vector>
using namespace std;
int main() {
// 读取输入规模 n 和目标值 x
int n, x;
cin >> n >> x;
vector<int> arr(n, 0);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
// 用于保存最终结果的索引对 [start, end]
int index[] = {};
cur = ;
prev = ;
sum = ;
(cur < n) {
sum += arr[cur];
(sum >= x) {
(index[] == && index[] == ) {
index[] = prev;
index[] = cur;
sum -= arr[prev++];
;
}
length = index[] - index[];
camplen = cur - prev;
(length == camplen || length > camplen) {
(prev < index[] || length > camplen) {
index[] = prev;
index[] = cur;
}
}
sum -= arr[prev++];
}
cur++;
}
cout << index[] + << << index[] + << endl;
;
}


