题目


解法1:滑动窗口

点击查看代码
#include<iostream>
#include<vector>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> diamonds(n + 1); // 1-based
    for (int i = 1; i <= n; ++i) {
        cin >> diamonds[i];
    }

    int i = 1, j = 1, sum = 0;
    int min_exceed = 1e9;
    vector<pair<int, int>> result;

    while (true) {
        while (j <= n && sum < m) {
            sum += diamonds[j++];
        }

        if (sum < m) break; // 已经不能凑出m了

        if (sum >= m) {
            if (sum < min_exceed) {
                min_exceed = sum;
                result.clear();
                result.push_back({i, j - 1});
            } else if (sum == min_exceed) {
                result.push_back({i, j - 1});
            }
        }

        sum -= diamonds[i++];
    }

    for (auto &p : result) {
        cout << p.first << "-" << p.second << endl;
    }

    return 0;
}

解法2:二分查找

点击查看代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;

    vector<int> diamonds(n + 1);         // 1-based
    vector<int> prefix_sum(n + 1, 0);    // 前缀和

    for (int i = 1; i <= n; ++i) {
        cin >> diamonds[i];
        prefix_sum[i] = prefix_sum[i - 1] + diamonds[i];
    }

    vector<pair<int, int>> result;
    int min_exceed = 1e9;

    for (int i = 0; i < n; ++i) {
        // 二分查找 j 使得 prefix_sum[j] - prefix_sum[i] >= m
        int left = i + 1, right = n, best_j = -1;
        while (left <= right) {
            int mid = (left + right) / 2;
            int sum = prefix_sum[mid] - prefix_sum[i];
            if (sum >= m) {
                best_j = mid;
                right = mid - 1;  // 尝试更短的区间
            } else {
                left = mid + 1;
            }
        }

        if (best_j != -1) {
            int sum = prefix_sum[best_j] - prefix_sum[i];
            if (sum < min_exceed) {
                min_exceed = sum;
                result.clear();
                result.push_back({i + 1, best_j});
            } else if (sum == min_exceed) {
                result.push_back({i + 1, best_j});
            }
        }
    }

    for (auto& p : result) {
        cout << p.first << "-" << p.second << endl;
    }

    return 0;
}