思路:
这道题暴力肯定不行,10^5绝对超限,但是可以骗分(*^▽^*),
真正的做法是two pointers的做法,
因为求区间【l,r】内的和,所以用p代表左指针,q代表右指针,然后记录区间【p,q】内的和,
每次求出这个区间内大于等于m的值,然后更新l,再查找下一个大于等于m的r。
注意:考虑最大值比10^5*10^3大。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int INF = 999999999; //这里要大于10^5*10^3 = 10^8的最大数据
const int maxn = 100100;
int a[maxn];
struct Node{
int x,y;
Node(int l,int r):x(l),y(r){}
};
vector <Node> vc;
int main(void)
{
int n,m,i,j,x,y;
scanf("%d%d",&n,&m);a[0]=0;
for(i=1;i<=n;i++) scanf("%d",&a[i]);
int p=0,q=1,sum=0,Min=INF; //记录左右指针
for(;p<=n;p++){
sum-=a[p]; //sum每次-a[p]表示更新左区间
while(q<=n&&sum<m) sum+=a[q++]; //更新右区间,找到第一个大于等于m的位置
if(sum>=m&&sum<Min){
Min = sum; //更新Min的值
vc.clear();
vc.push_back(Node(p+1,q-1));
}
else if(Min==sum){//考察比与sum相同的那个
vc.push_back(Node(p+1,q-1));
}
//这里不用更新右区间,因为原来的[l,r]区间是符合最小要求的,左区间被更新后区间和变小,所以右区间也要向前才能满足要求。
}
for(i=0,x=vc.size();i<x;i++) printf("%d-%d\n",vc[i].x,vc[i].y);
return 0;
}