这题求的非空区间可以是整个数组内的任意一个区间,刚开始我是想用一个for和一个while
for(int i=0; i<n; i++) { l=0,sum=0; while(l<i) { int j=l; for(int k=j; k<i; k++) { sum+=a[k]; if(sum>=k) { s++; break; ) } l++; }}
但因为数据太大,肯定要超时(chaoshigetout),所以改成两个指针,l和r代表非空区间的大小,因为所有的都是正整数,所以当右指针找到大于k的地方时,在左指针不动的情况下继续向右扩大肯定也是大于k的,然后再进行左指针的向右移动一直到不大于k或者=r为止;比起上面的省略的就是每次右指针右移的时候都会重新进行一遍整个区间的添加 和当对同一个区间的重复添加
#include<bits/stdc++.h> using namespace std; const long long N = 1e6 + 10; typedef long long ll; int main() { ll n, k;//n:数组长度,k:比较的大小 cin >> n >> k; ll a[N]; for (ll i = 0; i < n; ++i) { cin >> a[i]; } ll s = 0;//非空区间的个数 ll sum = 0;//当前非空区间所有元素的大小 ll l = 0, r = 0;//左指针和右指针 while (r < n){//数组是从0开始存的,所以<n sum += a[r];//先扩大右指针一直到非空区间大于k为止 while (sum >= k) {//当这个非空区间大于k时 s += n - r;//因为这里都是正整数,所以当左指针到右指针之间的非空区间大于k时,右指针继续右移也会大于k sum -= a[l++];//移动左指针 } ++r;//当左指针移动到非空区间小于k时,继续移动右指针 } cout << s <<"\n"; return 0; }