POJ 2566 Bound Found 【Two Pointers】

題目鏈接

題意

給一串數列,再給一個目標值(非負),求這個數列中最接近目標值的區間和的絕對值

分析

原數列中的數有正有負,用Two Pointers不能保證向左向右移動一定會使區間和變大或變小,而排序又會打亂數列的順序。同樣,如果先算出前綴和,在前綴和上移動同樣不能保證向着期望的方向變化。但是,對前綴和排序不影響結果,只要記錄某個前綴和對應的原下標,排序後再用Two Pointers,就可以解決這個問題

AC代碼

//POJ 2566 Bound Found
//AC 2016-8-1 14:48:13
//Two Pointers
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <set>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <list>
#include <sstream>
#include <stack>
using namespace std;

#define cls(x) memset(x,0,sizeof x)
#define inf(x) memset(x,0x3f,sizeof x)
#define neg(x) memset(x,-1,sizeof x)
#define ninf(x) memset(x,0xc0,sizeof x)
#define st0(x) memset(x,false,sizeof x)
#define st1(x) memset(x,true,sizeof x)
#define INF 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define bug cout<<"here"<<endl;
//#define debug

struct psum
{
    int v;
    int pos;
    bool operator< (const psum &rhs) const
    {
        if(v==rhs.v)
            return pos<rhs.pos;
        return v<rhs.v;
    }
}prefix[100010];

int n,k;

int main()
{
    #ifdef debug
        freopen("E:\\Documents\\code\\input.txt","r",stdin);
        freopen("E:\\Documents\\code\\output.txt","w",stdout);
    #endif
    while(scanf("%d %d",&n,&k)!=EOF&&n+k)
    {
        int sum=0,t;
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&t);
            sum+=t;
            prefix[i].pos=i;
            prefix[i].v=sum;
        }
        prefix[0].v=prefix[0].pos=0;
        sort(prefix,prefix+n+1);
        while(k--)
        {
            scanf("%d",&t);
            int p=1,q=0;
            int res=-INF,fp,fq,cur;
            while(p<=n&&q<=n)
            {
                cur=prefix[p].v-prefix[q].v;
                if(abs(cur-t)<abs(res-t))
                {
                    res=cur;
                    fp=p;
                    fq=q;
                }
                if(cur<t) ++p;
                else if(cur>t) ++q;
                else break;
                if(p==q) ++p;
            }
            p=max(prefix[fp].pos,prefix[fq].pos);
            q=min(prefix[fp].pos,prefix[fq].pos)+1;
            printf("%d %d %d\n",res,q,p);
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章