POJ 2566 Bound Found 题解 《挑战程序设计竞赛》 � 码农场


Signals of most probably extra-terrestrial origin have been received and digitalized by The Aeronautic and Space Administration (that must be going through a defiant phase: "But I want to use feet, not meters!"). Each signal seems to come in two parts: a sequence of n integer values and a non-negative integer t. We'll not go into details, but researchers found out that a signal encodes two integer values. These can be found as the lower and upper bound of a subrange of the sequence whose absolute value of its sum is closest to t.

You are given the sequence of n integers and the non-negative target t. You are to find a non-empty range of the sequence (i.e. a continuous subsequence) and output its lower index l and its upper index u. The absolute value of the sum of the values of the sequence from the l-th to the u-th element (inclusive) must be at least as close to t as the absolute value of the sum of any other non-empty range.
Input
The input file contains several test cases. Each test case starts with two numbers n and k. Input is terminated by n=k=0. Otherwise, 1<=n<=100000 and there follow n integers with absolute values <=10000 which constitute the sequence. Then follow k queries for this sequence. Each query is a target t with 0<=t<=1000000000.
Output
For each query output 3 numbers on a line: some closest absolute sum and the lower and upper indices of some range where this absolute sum is achieved. Possible indices start with 1 and go up to n
上下界:从数列中找出连续序列,使得和的绝对值与目标数之差最小。
从数列中找出连续序列,使得和的绝对值与目标数之差最小 

因为前缀和不单调,所以需要先排个序,之后就是尺取法了:首尾分别逐步向前挪动,挪动过程中记录答案 



3.2常用技巧精选(一)

尺取法

因为前缀和不单调,所以需要先排个序。之后就是尺取法了:首尾分别逐步向前挪动,挪动过程中记录答案
http://blog.csdn.net/wiking__acm/article/details/9910415
题意就是找一个连续的子区间,使它的和的绝对值最接近target。这题的做法是先预处理出前缀和,然后对前缀和进行排序,再用尺取法贪心的去找最合适的区间,要注意的是尺取法时首尾指针一定不能相同,因为这时区间相减结果为0,但实际上区间为空,这是不存在的,可能会产生错误的结果。处理时,把(0,0)这个点也放进数组一起排序,比单独判断起点为1的区间更方便。还有ans初始化的值INF一定要大于t的最大值。最后说说这个题最重要的突破口,对前缀和排序。为什么这么做是对的呢?以为这题是取区间的和的绝对值,所以所以用sum[r]-sum[l] 和 sum[l]-sum[r]是没有区别的。这样排序后,把原来无序的前缀和变成有序的了,就便于枚举的处理,并且不影响最终结果。


题意:对一个长度为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)]。

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

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

尺取法的一般用法就是对于一个连续区间求解某些最值,此题便是如此

因为前缀和不单调,所以需要先排序。在原数组开头添加0,求出前缀数组。题目即转化为在前缀数组中找pre[i],pre[j],两者之差最接近t,。对于每次找到的2个下标分别为i和j的2个数,所对应a的区间为[min(i, j) + 1, max(i, j)]。
那么前缀数组排序后,尺取法便可以求得最接近t的值。
首先求前缀和。由于是绝对值与t比较,所以左右断点交换没有影响,故可以将求好的前缀和排序。
然后用尺取法。如果当前区间各个数和的绝对值小于ans则更新。
比较  当前区间各个数的和 与t的大小  改变区间的左右端点。
比t大,则左端点++ ; 否则,右端点++。

  1. typedef  pair<intint> P;  
  2. typedef long long LL;  
  3.   
  4. P p[maxn];  
  5.   
  6. int Abs(int x){return x<0?-x:x;}  
  7. int n;  
  8.   
  9. void query(int tar){  
  10.     int s = 0,e = 1,Min = INF;  
  11.     int ansl,ansr,ansx;  
  12.     while(s <= n && e <= n){  
  13.         int tem = p[e].first-p[s].first;  
  14.         if(Abs(tem-tar) < Min){  
  15.             Min = Abs(tem-tar);  
  16.             ansx = tem;  
  17.             ansl = p[s].second;  
  18.             ansr = p[e].second;  
  19.         }  
  20.         if(tem > tar) s++;  
  21.         else if(tem < tar) e++;  
  22.         else break;  
  23.         if(s == e) e++;  
  24.     }  
  25.     if(ansl > ansr) swap(ansl,ansr);  
  26.     printf("%d %d %d\n",ansx,ansl+1,ansr);  
  27. }  
  28.   
  29. int main(){  
  30.     int m;  
  31.     while(scanf("%d%d",&n,&m)){  
  32.         if(n == 0 && m == 0) break;  
  33.         p[0] = P(0,0);  
  34.         int sum = 0;  
  35.         for(int i = 1;i <= n;i++){  
  36.             int tem;  
  37.             scanf("%d",&tem);  
  38.             sum += tem;  
  39.             p[i] = P(sum,i);  
  40.         }  
  41.         sort(p,p+n+1);  
  42.         while(m--){  
  43.             int x;  
  44.             scanf("%d",&x);  
  45.             query(x);  
  46.         }  
  47.     }  
  48.     return 0;  

int a[MAX_N];
pair<intint> accumulation[MAX_N]; // sum <-> index
// 更新答案
int get_sum(int& result, const int& l, const int& r, const int& t, int& from, int& to)
{
    if (l >= r)
    {
        return INT_MIN;    // 不合法,终止
    }
    int sum = accumulation[r].first - accumulation[l].first;
    if (abs(t - sum) < abs(t - result))   // 顺便记录一下可能的答案
    {
        result = sum;
        from = min(accumulation[l].second, accumulation[r].second);
        to = max(accumulation[l].second, accumulation[r].second);
    }
    return sum;
}
///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
    freopen("in.txt""r", stdin);
    freopen("out.txt""w", stdout);
#endif
    int n, k;
    while (cin >> n >> k && n)
    {
        for (int i = 0; i < n; ++i)
        {
            cin >> a[i];
        }
        accumulation[0] = make_pair(0, 0);   // 多留一个,待会儿免得下标跟答案对不上
        for (int i = 0; i < n; ++i)
        {
            accumulation[i + 1] = make_pair(accumulation[i].first + a[i], i + 1);
        }
        sort(accumulation, accumulation + n + 1);
        while (k--)
        {
            int t;
            cin >> t;
            // 输入结束
            int l = 0, r = 0, sum = 0x80808080, from, to, result = 0x80808080;
            for (;;)
            {
                while (r < n && sum < t)
                {
                    sum = get_sum(result, l, ++r, t, from, to);  // ++r 头部前进
                }
                if (sum < t)
                {
                    break;
                }
                sum = get_sum(result, ++l, r, t, from, to);  // ++l 尾部前进
            }
            cout << result << ' ' << from + 1 << ' ' << to << endl;
        }
    }
#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    system("out.txt");
#endif
    return 0;
}
https://blog.csdn.net/V5ZSQ/article/details/46840419
pair<int,int> P[maxn];
void solve(int x)
{
    int l=0,r=1,Min=INF;
    int ansx,ansl,ansr;
    while(l<=n&&r<=n)
    {
        int y=P[r].first-P[l].first;
        if(abs(y-x)<Min)//更新差值的最小值
        {
            Min=abs(y-x);
            ansx=y;
            ansl=P[l].second;
            ansr=P[r].second;
        }
        if(y<x) r++;//小于目标值右标前进
        else if(y>x) l++;//大于目标值左标前进
            else break;//等于目标值退出循环
        if(l==r)//左右标相同则右标前进
            r++;
    }
    if(ansl>ansr)//左标必须小于等于右标
        swap(ansl,ansr);
    printf("%d %d %d\n",ansx,ansl+1,ansr); 
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            break;
        P[0]=pair<int,int>(0,0);
        int d,sum=0;
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&d);
            sum+=d;//前缀和
            P[i]=pair<int,int>(sum,i);
        }
        sort(P,P+n+1);//对前缀和排序
        while(m--)//m次查询
        {
            int x;
            scanf("%d",&x);
            solve(x);
        }
    }
    return 0;
}
Read full article from POJ 2566 Bound Found 题解 《挑战程序设计竞赛》 � 码农场

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts