题目来源
题目描述
题目解析
因为是正整数,所以它一定大于0
暴力
int SubArrayCount(std::vector<int> &nums, int k){
int N = nums.size();
int cnt = 0;
for (int i = 0; i < N; ++i) {
// 这部分可以用前缀和来优化
int sum = 0;
int j = i;
for (j = i; j < N; ++j) {
sum += nums[j];
if(sum >= k){
break;
}
}
if(j != N){
cnt += N - j; // 找到了满足要求的,后面的所有区间也一定满足要求
} // 如果j == N,那么说明没有满足要求
}
return cnt;
}
int SubArrayCount(std::vector<int> &nums, int k){
int N = nums.size();
int cnt = 0;
for (int i = 0; i < N; ++i) {
int sum = 0;
int j = i;
for (j = i; j >= 0; --j) {
sum += nums[j];
if(sum >= k){
break;
}
}
cnt += j + 1;
}
return cnt;
}
怎么用前缀数组优化
(1)生成一个前缀数组
(2)对于每一个prefix[i],在[0…i]区间上找大于prefix[i] - k的第一个索引
//要求一共有多少个
int SubArrayCount(std::vector<int> &nums, int k){
int N = nums.size();
// 生成前缀数组
std::vector<int> prefix(N + 1, 0);
for (int i = 1; i < prefix.size(); ++i) {
prefix[i] = prefix[i - 1] + nums[i - 1];
}
int cnt = 0;
for (int i = 1; i < prefix.size(); ++i) {
if(prefix[i] >= k){ // prefix[i
int pos = upper_bound(prefix.begin(), prefix.begin() + i, prefix[i] - k) - prefix.begin();
cnt += pos;
}
}
return cnt;
}
关于输入
int main(){
int N, x;
std::cin >> N >> x;
std::vector<int> vec(N);
for (int i = 0; i < N; ++i) {
std::cin >> vec[i];
}
std::cout << SubArrayCount(vec, x);
}
对数器
#include <assert.h>
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <iterator>
#include <random>
std::default_random_engine e;
std::vector<int> generateRandom(int maxLen, int minValue, int maxValue){
std::uniform_int_distribution<int> distS(1, maxLen);
std::uniform_int_distribution<int> distV(minValue, maxValue);
std::vector<int> arr;
int size = maxLen;
arr.resize(size);
for (int i = 0; i < size; ++i) {
arr[i] = distV(e);
}
return arr;
}
int generateNum(int minValue, int maxValue){
std::uniform_int_distribution<int> distV(minValue, maxValue);
return distV(e);
}
int main() {
e.seed(time(NULL));
int testCount(1000); // epoch
int maxSize(1000); // max size of the vector
int minValue(0); // min value
int maxValue(100); // maxvalue
for (int i = 0; i < testCount; ++i) {
std::vector<int> vec1 = generateRandom(maxSize, minValue, maxValue);
int x = generateNum(0, 10000);
int a = SubArrayCount(vec1, x);
int b = SubArrayCount2(vec1, x);
if(a != b){
std::copy(vec1.begin(), vec1.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << " error !!!\n";
break;
}
}
return 0;
}