题意:
给出n个整数的序列和非负目标t,要求找到最接近t的连续子序列的和的绝对值,输出子序列和以及其首尾下标。
样本输入
5 1
-10 -5 0 5 10
3
10 2
-9 8 -7 6 -5 4 -3 2 -1 0
5 11
15 2
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
15 100
0 0
样本输出
5 4 4
5 2 8
9 1 1
15 1 15
15 1 15
#include <iostream>
#include<stdio.h>
#include<set>
#include<map>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
//#define pii pair<ll,int>
//pii sum[100005];
struct node
{
ll first;
int second;
}sum[100005];
bool cmp(node x,node y)
{
return x.first<y.first;
}
ll n,m,t;
ll mabs(ll x)
{
return x>0?x:-x;
}
//void init()
//{
// ll a,y=0;
// sum[0]=pii(0,0);
// for(int i=1; i<=n; i++)
// {
// scanf("%lld",&a);
// y+=a;
// sum[i]=pii(y,i);
// }
// sort(sum,sum+n+1);
//}
void init()
{
ll a,y=0;
sum[0].first=0;
sum[0].second=0;
for(int i=1; i<=n; i++)
{
scanf("%lld",&a);
y+=a;
sum[i].first=y;
sum[i].second=i;
}
sort(sum,sum+n+1,cmp);
}
int main()
{
while(~scanf("%lld%lld",&n,&m))
{
if(n==0&&m==0)
break;
init();
for(int i=1; i<=m; i++)
{
scanf("%lld",&t);
int l=0,r=1,minn=inf,ans,ansl,ansr;
while(r<=n&&minn)
{
int d=sum[r].first-sum[l].first;
if(mabs(d-t)<=minn)
{
minn=mabs(d-t);
ans=d;
ansl=sum[l].second;
ansr=sum[r].second;
}
if(d<t)
r++;
if(d>t)
l++;
if(l==r)
r++;
}
if(ansl>ansr)
swap(ansl,ansr);
printf("%d %d %d\n",ans,ansl+1,ansr);
}
}
return 0;
}