• POJ 2566 Bound Found


    题意 : 给你n个数字,这些数字可正可负,再给你个数字t,
    求在这个数列中一个连续的子序列,和的绝对值 与t相差最小;

    数据范围较大, 考虑数字没有负数的情况,
    能够想到用尺取法解决, (关于尺取法, 自己感受一下这东西的奇妙, 不好说, 理解了之后也没什么好说, 实现主要是首尾指针的移动), 那么增加了负数之后, 发现题目中要的是序列的绝对值, 发现直接排序前缀和即使用后面的前缀和减去前面的前缀和, 也没有关系;

    但主要需要注意的是本题细节比较烦, 在POJ上WA了3,4次, 这里提示一下
    注意如果给出的值为0时的处理, 还有就是自己多想几组小数据来调试, 调的很恶心, 但也很享受, 适合做尺取的好题

    /*
    *题意:给你n个数字,这些数字可正可负,再给你个数字t,
    *求在这个数列中一个连续的子序列,和的绝对值 与t相差最小
    *                                        ————Galaxy TODO
    */
    #include <cstdio>
    #include <algorithm>
    
    typedef long long LL;
    
    const int N = 1e5 + 10;
    #define C c = getchar()
    #define rep(i, s, t) for(int i = s; i <= t; ++i)
    
    LL abs(LL x) {return x>0?x:-x;}
    int read(int x=0, int t=1) {char C;
        while(c<'0' || c>'9') {if(c=='-') t=-1; C;}
        while(c>='0' && c<='9') x = x*10 + c-'0', C;
        return x*t;
    }
    
    struct Sum_tot{
        LL sum; int rk;
        //Sum_tot(int _sum, int _rk) {sum = _sum; rk = _rk;}
        bool operator < (const Sum_tot& rhs) const{
            return sum < rhs.sum;
        }
    }P[N];
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.in", "r", stdin);
        freopen("res.out", "w", stdout);
    #endif
        int n, T; LL S;
        while(scanf("%d%d", &n, &T) == 2 && n+T) {
            P[0].sum = 0, P[0].rk = 0;
            rep(i, 1, n) P[i] = ((Sum_tot) {P[i-1].sum+read(), i});
    
            std :: sort(P, P+n+1);
        //  rep(i, 0, n) printf("%lld%c", P[i].sum, i^n?' ':'
    ');
    
            while(T--) {
                scanf("%lld", &S);
                int ansl=n, ansr=n;
                int l = n-1, r = n;
                LL res = 1LL << 62;
                while(r > l) {
            //      printf("%d %d__debug1
    ", l, r);
                    while(P[r].sum - P[l].sum <= S && l >= 0) { 
                        if(abs(P[r].sum-P[l].sum-S) < abs(S-res)) {
                            res = P[r].sum - P[l].sum;
                            ansl = P[l].rk, ansr = P[r].rk;
                        }
                        --l;
                    }
                    if(l < 0) break;
        //          printf("%d %d__debug2
    ", l, r);
    
                    while(P[r].sum - P[l].sum >= S && r > l) { 
                        if(P[r].sum-P[l].sum-S < abs(res-S)) {
                            res = P[r].sum - P[l].sum;
                            ansl = P[l].rk, ansr = P[r].rk;
                        }
                        --r;
                    }
                    if(r < 0) break;
                    if(l == r) --l;
                    if(l < 0) break;
            //      printf("%d %d__debug3
    ", l, r);
                    if(res == S) break;
                }
                if(ansl+1 > ansr) std::swap(ansl, ansr);
                printf("%lld %d %d
    ", res, ansl+1, ansr);
            }
        }
        return 0;
    }
    //XXX
  • 相关阅读:
    Python (一)Tkinter窗口组件:Label
    Python (八)Tkinter窗口组件:Scrollbar
    Python (四)Tkinter窗口组件:Radiobutton
    Python (五)Tkinter窗口组件:LabelFrame
    Python (三)Tkinter窗口组件:Checkbutton
    Scrapy安装及相关知识点概括
    Python (九)Tkinter窗口组件:Scale
    Python (六)Tkinter窗口组件:Entry
    电脑通过蓝牙适配器连接手机与蓝牙耳机之经验
    Noi2018 归途
  • 原文地址:https://www.cnblogs.com/pbvrvnq/p/8530155.html
Copyright © 2020-2023  润新知