题目
![]()
解法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;
}