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

POJ 2566 Bound Found

时间:2015-07-27 15:03:14      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:前缀和   排序   尺取法   

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

题意:对一个长度为n的数列,做k次查询,每次查询一个数t,求原数列中的一个子区间[l, r],使得该子区间的和的绝对值最接近t。

思路:在原数列开头添加一个0,处理好现数列a[N]的前缀和pre[N]。则原问题转化为在前缀数组中求2个数pre[i],pre[j]的差的绝对值最接近t的。对于每次找到的2个下标分别为i和j的2个数,所对应a的区间为[min(i, j) + 1, max(i, j)]。

那么将前缀和数组排序后,即可用尺取法得到最接近的值。

注意的是:排序时需要保留原来的下标值,以便于求区间。

代码如下

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;

const int N = 1e5 + 10;
const int INF = 0x7fffffff;

struct Presum {
    int sum;
    int id;
};

int n, k;
int a[N];
Presum pre[N];

bool cmp(Presum a, Presum b) {
    return a.sum < b.sum;
}

int main() {


    while (scanf("%d%d", &n, &k) != EOF && n && k) {
        pre[0].sum = 0;
        pre[0].id = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            pre[i].sum = pre[i - 1].sum + a[i];
            pre[i].id = i;
        }
        sort(pre, pre + n + 1, cmp);

        for (int i_q = 0; i_q < k; i_q++) {
            int t;
            scanf("%d", &t);
            int ansl, ansr, ans;
            int l = 0, r = 1;
            int Min = INF;
            while (r <= n) {
                int sub = pre[r].sum - pre[l].sum;
                if (abs(sub - t) < Min) {
                    Min = abs(sub - t);
                    ansl = min(pre[l].id, pre[r].id) + 1;
                    ansr = max(pre[l].id, pre[r].id);
                    ans = sub;
                }
                if (sub < t)
                    r++;
                else if (sub > t)
                    l++;
                else break;
                if (l == r)
                    r++;
            }
            printf("%d %d %d\n", ans, ansl, ansr);
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 2566 Bound Found

标签:前缀和   排序   尺取法   

原文地址:http://blog.csdn.net/u014357885/article/details/47084279

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