本题思路:
用sum数组计算第一颗钻石到第i颗钻石价值的总和,然后从序列i开始,对i和n做二分运算,每次循环得出一个数j,i到j之间的钻石价值最接近m(如果不能等于m,则大于m优先,如果没有大于m的,小于m优先)
代码如下:
#include <iostream>
#include <vector>
using namespace std;
int n,m,sum[100001],j,tans;
void fun(int i){
int l=i,r=n;
while(l<r){
int mid=(l+r)/2;
if (sum[mid]-sum[i-1]>=m){
r=mid;
}
else{
l=mid+1;
}
}
j=r;
tans=sum[j]-sum[i-1];
}
int main(){
int t;
scanf("%d%d",&n,&m);
vector<int> v;
for (int i=1;i<=n;i++){
scanf("%d",&t);
sum[i]+=sum[i-1]+t;
}
int mind=sum[n];
for (int i=1;i<=n;i++){
fun(i);
if (tans>mind) continue;
if (tans>=m){
if (tans<mind){
v.clear();
mind=tans;
}
v.push_back(i);
v.push_back(j);
}
}
for (int i=0;i<v.size();i+=2){
printf("%d-%d\n",v[i],v[i+1]);
}
return 0;
}