注意要点:
- 首先看两个函数定义
lower_bound( begin,end,num)
从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,
找到返回该数字的地址,不存在则返回end。
通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num)
从数组的begin位置到end-1位置二分查找第一个大于num的数字,
找到返回该数字的地址,不存在则返回end。
通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
-
求连续子序列的和,我们可以构建sum函数,简化时间复杂度。
这里定义,sum[i]=a[1]+a[2]+…+a[i] -
lower_bound比upper_bound好一点,upper_bound 需要注意使用upper_bound求得的位置不一定恰好是右端点的位置(可能需要减一)。
-
请注意,如何判断lower_bound与upper_bound的查询是否成功?
code中 index<=n 就是用来判断这个的
满分题解(使用lower_bound() )
#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<cctype>
#include<algorithm>
using namespace std;
const int inf = 1000000000;
const int maxn = 100005;
int n, m;
int a[maxn];
int sum[maxn];
vector<pair<int, int> >res;
vector<pair<int, int> >nearvec;
void printvec(vector<pair<int, int> > v) {
for (int i = 0; i < v.size(); i++) {
printf("%d-%d\n", v[i].first, v[i].second);
}
}
int main() {
//freopen("input.txt", "r", stdin);
cin >> n >> m;
sum[0] = 0;
int total = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
total += a[i];
sum[i] = total;
}
int near = inf;
for (int i = 1; i <= n; i++) {
int index = lower_bound(sum + i, sum + n + 1, sum[i - 1] + m) - sum;
if (sum[index] - sum[i - 1] == m) {
near = sum[index] - sum[i - 1];
res.push_back(make_pair(i, index));
}
else if(index<=n && sum[index ] - sum[i - 1] <near){
near = sum[index ] - sum[i - 1];
nearvec.clear();
nearvec.push_back(make_pair(i, index ));
}else if(sum[index ] - sum[i - 1] == near){
nearvec.push_back(make_pair(i, index ));
}
}
if (res.size() != 0) {
printvec(res);
}
else {
printvec(nearvec);
}
return 0;
}
满分题解(使用upper_bound() )
#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<cctype>
#include<algorithm>
using namespace std;
const int inf = 1000000000;
const int maxn = 100005;
int n, m;
int a[maxn];
int sum[maxn];
vector<pair<int, int> >res;
vector<pair<int, int> >nearvec;
void printvec(vector<pair<int, int> > v) {
for (int i = 0; i < v.size(); i++) {
printf("%d-%d\n", v[i].first, v[i].second);
}
}
int main() {
//freopen("input.txt", "r", stdin);
cin >> n >> m;
sum[0] = 0;
int total = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
total += a[i];
sum[i] = total;
}
int near = inf;
for (int i = 1; i <= n; i++) {
int index = upper_bound(sum + i, sum + n + 1, sum[i - 1] + m) - sum;
if (sum[index - 1] - sum[i - 1] == m) {
near = sum[index - 1] - sum[i - 1];
res.push_back(make_pair(i, index - 1));
}
else if(index<=n&&sum[index ] - sum[i - 1] <near){
near = sum[index ] - sum[i - 1];
nearvec.clear();
nearvec.push_back(make_pair(i, index ));
}else if(sum[index ] - sum[i - 1] == near){
nearvec.push_back(make_pair(i, index ));
}
}
if (res.size() != 0) {
printvec(res);
}
else {
printvec(nearvec);
}
return 0;
}