码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2566:Bound Found(Two pointers)

时间:2017-01-18 00:37:41      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:typedef   pac   second   bre   pair   绝对值   利用   air   get   

 

【题目链接】 http://poj.org/problem?id=2566

 

【题目大意】

  给出一个序列,求一个子段和,使得其绝对值最接近给出值,
  输出这个区间的左右端点和区间和。

 

【题解】

  因为原序列的前缀和不具有单调性,难以处理,
  因此我们对前缀和进行排序,同时保留前缀和的右端点做标识作用,
  题目要求区段和的绝对值最接近目标,因此排序不会造成前后顺序变化造成的影响
  现在题目转化为在一个有序数列中,求一个数对,使得差值最接近给出数,
  利用单调性,可以尺取解决问题。

 

【代码】

#include <cstdio>
#include <utility>
#include <algorithm>
#include <climits>
using namespace std;
const int N=100010,INF=INT_MAX;
typedef pair<int,int> P;
int n,m,s,t,ans,ansl,ansr;
P p[N];
int main(){
    while(scanf("%d%d",&n,&m),n&&m){
        p[0]=P(s=0,0);
        for(int i=1;i<=n;i++)scanf("%d",&t),p[i]=P((s+=t),i);
        sort(p,p+n+1);
        while(m--){
            scanf("%d",&t);
            int l=0,r=1,Min=INF;
            while(l<=n&&r<=n){
                int tmp=p[r].first-p[l].first;
                if(abs(tmp-t)<Min){
                    Min=abs(tmp-t); ans=tmp;
                    ansl=p[l].second; ansr=p[r].second;
                }if(tmp>t)l++;else if(tmp<t)r++;else break;
                if(l==r)r++;
            }if(ansl>ansr)swap(ansl,ansr);
            printf("%d %d %d\n",ans,ansl+1,ansr);
        }
    }return 0;
}

POJ 2566:Bound Found(Two pointers)

标签:typedef   pac   second   bre   pair   绝对值   利用   air   get   

原文地址:http://www.cnblogs.com/forever97/p/poj2566.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!