Bound Found POJ

来源:互联网 发布:悔女知之乎的意思 编辑:程序博客网 时间:2024/06/09 22:58

题意 就是给一串序列 在给一个t 求一段区间的加和绝对值与t最小的值与区间左右端点是多少 



思路 这道题一开始不知道如何去做 用尺取法求区间但是因为区间中存在负数没有单调性  没有特殊的特征

若对区间求一下前缀和 就使整个区间有了单调性   由于绝对值情况下 没有前后 所以我们队前缀和后的序列排序

对排序后的前缀和数串进行尺取 若是l和r内的数比t小r++ 比t大就l++ 若相等就break



code:


#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;const int inf = 100010;pair<int,int>sum[inf];int main(){int n,k;while(cin>>n>>k,n+k){int tem=0;sum[0]=make_pair(0,0);for(int i=1;i<=n;i++){int p;scanf("%d",&p);tem+=p;sum[i]=make_pair(tem,i);}sort(sum,sum+n+1);//for(int i=0;i<=n;i++)//cout<<sum[i].first<<" "<<sum[i].second<<endl;while(k--){int t;scanf("%d",&t);int al,ar,ami,l=0,r=1,MAX = 2000000000;while(r<=n&&MAX){int ee = sum[r].first-sum[l].first;if(abs(ee-t)<MAX){MAX = abs(ee-t);ami = abs(ee);//cout<<ami<<" "<<l<<" "<<r<<" 123"<<endl;al = sum[l].second;ar = sum[r].second;}if(ee<t)r++;else if(ee>t)l++;else break;if(l==r)r++;}printf("%d %d %d\n",ami,min(al,ar)+1,max(al,ar));}}return 0;}


原创粉丝点击