POJ 3061 Subsequence

题目链接:POJ 3061 Subsequence

题目大意:
给出了一个由\(N\)个正整数\((10 < N < 100000)\)组成的序列,每个都小于或等于\(10000\),并给出一个正整数\(S(S<100000000)\)。编写一个程序,求出序列中连续元素之和大于或等于\(S\)的子序列的最小长度。

题解:
用前缀和存储数据,用尺取法维护当前区间。
不断右移\(q\)指针直到\(sum[q] - sum[p] >= s\),当\(sum[q] - sum[p] >= s\)时不断右移\(p\)指针,记录\(q-p\)的最小值。

#include <algorithm>
#include <iostream>
using namespace std;

int sum[100010], n, s, t; // 前缀和

int main() {
    ios::sync_with_stdio(false);
    cin >> t;
    sum[0] = 0;
    while (t--) {
        cin >> n >> s;
        int p = 0, q = 0, num;
        int ans = 0x3f3f3f3f;
        for (int i = 1; i <= n; i++) {
            cin >> num;
            sum[i] = sum[i - 1] + num;
        }
        while (q <= n) {
            while (sum[q] - sum[p] < s && q <= n) {
                q++;
            }
            if (q > n) break;
            while (sum[q] - sum[p] >= s) {
                ans = min(ans, q - p);
                p++;
            }
        }
        cout << (ans == 0x3f3f3f3f ? 0 : ans) << endl;
    }
    return 0;
}
posted @ 2021-09-02 20:34  ZZHHOOUU  阅读(22)  评论(0编辑  收藏  举报