1. 程式人生 > >POJ 2566 尺取法(進階題)

POJ 2566 尺取法(進階題)

style tin 思路 acc ons achieved com per ber

Bound Found
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 4297 Accepted: 1351 Special Judge

Description

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.

Sample Input

5 1
-10 -5 0 5 10
3
10 2
-9 8 -7 6 -5 4 -3 2 -1 0
5 11
15 2
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
15 100
0 0

Sample Output

5 4 4
5 2 8
9 1 1
15 1 15
15 1 15

Source

Ulm Local 2001 題意:就是找一個連續的子區間,使它的和的絕對值最接近target, 區間內的元素可正可負。 思路:待會再補。。。 代碼:
 1 #include "stdio.h"
 2 #include "stdlib.h"
 3 #include "iostream"
 4 #include "algorithm"
 5 #include "string"
 6 #include "cstring"
 7 #include "queue"
 8 #include "cmath"
 9 #include "vector"
10 #include "map"
11 #include "set"
12 #define db double
13 #define inf 0x3f3f3f
14 #define mj
15 //#define ll long long
16 #define unsigned long long ull;
17 using namespace std;
18 const int mod = 1000000007;
19 const int N=1e6+5;
20 const double eps = 1e-10;
21 typedef pair<int, int > pii;
22 pii p[N];
23 int n, m, k;
24 void f(int k)
25 {
26     int l = 0, r = 1, ll, rr, v, mi = inf;
27     while (l<=n&&r<=n&&mi!=0)
28     {
29         int tmp=p[r].first - p[l].first;
30         if (abs(tmp - k) < mi)
31         {
32             mi = abs(tmp - k);
33             rr = p[r].second;
34             ll = p[l].second;
35             v = tmp;
36         }
37         if (tmp> k)
38             l++;
39         else if (tmp < k)
40             r++;
41         else
42             break;
43         if (r == l)
44             r++;
45     }
46     if(ll>rr) swap(ll,rr);//因為ll和rr大小沒有必然關系()取絕對值,所以//要交換
47     printf("%d %d %d\n", v, ll+1, rr);
48 }
49 int main()
50 {
51     while (scanf("%d %d", &n, &m)==2,n||m)
52     {
53         p[0]=make_pair(0, 0);
54         for (int i = 1; i <= n; i++)
55         {
56             scanf("%d", &p[i].first);
57             p[i].first += p[i - 1].first;
58             p[i].second = i;
59         }
60         sort(p, p + n + 1);
61         while (m--)
62         {
63             scanf("%d", &k);
64             f(k);
65         }
66     }
67     return 0;
68 }

POJ 2566 尺取法(進階題)