PAT-A1044-Shopping in Mars (25)

无代码

题目描述

Shopping in Mars is quite a different experience. The Mars people pay by chained diamonds. Each diamond has a value (in Mars dollars M$). When making the payment, the chain can be cut at any position for only once and some of the diamonds are taken off the chain one by one. Once a diamond is off the chain, it cannot be taken back. For example, if we have a chain of 8 diamonds with values M$3, 2, 1, 5, 4, 6, 8, 7, and we must pay M$15. We may have 3 options:

  1. Cut the chain between 4 and 6, and take off the diamonds from the position 1 to 5 (with values 3+2+1+5+4=15).
  2. Cut before 5 or after 6, and take off the diamonds from the position 4 to 6 (with values 5+4+6=15).
  3. Cut before 8, and take off the diamonds from the position 7 to 8 (with values 8+7=15).

Now given the chain of diamond values and the amount that a customer has to pay, you are supposed to list all the paying options for the customer.

If it is impossible to pay the exact amount, you must suggest solutions with minimum lost.

题意

给出一个数字序列与一个数S,在数字序列中求出所有和值为S的连续子序列(区间下标左端点小的先输出,左端点相同时右端点小的先输出)。若没有这样的序列,求出和值恰好大于S的子序列(即在所有和值大于S的子序列中和值最接近S)。假设序列下标从1开始。

输入格式

Each input file contains one test case. For each case, the first line contains 2 numbers: N (≤105), the total number of diamonds on the chain, and M (≤108), the amount that the customer has to pay. Then the next line contains N positive numbers D1⋯DN (Di≤103 for all i=1,⋯,N) which are the values of the diamonds. All the numbers in a line are separated by a space.

输出格式

For each test case, print i-j in a line for each pair of ij such that Di + … + Dj = M. Note that if there are more than one solution, all the solutions must be printed in increasing order of i.

If there is no solution, output i-j for pairs of ij such that Di + … + Dj >M with (Di + … + Dj −M) minimized. Again all the solutions must be printed in increasing order of i.

It is guaranteed that the total value of diamonds is sufficient to pay the given amount.

输入样例1

16 15
3 2 1 5 4 6 8 7 16 10 15 11 9 12 14 13

输出样例1

1-5
4-6
7-8
11-11

输入样例2

5 13
2 4 5 7 9

输入样例2

2-4
4-5

题目信息

作者:CHEN, Yue

单位:浙江大学

代码长度限制:16 KB

时间限制:300 ms

内存限制:64 MB

题目类型:二分-寻找有序数列第一个满足某条件的元素的位置

分析

设 Sum[i] 表示 a[1] 倒 a[i] 的和,也就是 Sum[i] = a[1] + a[2] + a[3] + …… + a[i]。

因为 a 序列都是正值,所以 Sum 是递增的,这样如果我们要判断 第 c 个数到第 d 个数的和,只要算 Sum[d] - Sum[c]。

那么这道题就转换成了判断 Sum[i] - Sum[j] 的值是否为目标值或者接近目标值

我们可以从0开始:Sum[j] - Sum[0],并在每次遍历中判断出 Sum[j] - Sum[i] 距离目标值的远近:Sum[j] - Sum[i] - 目标值,每次取最小值

int target = 要支付的价格,也就是目标值
int min = Integer.MAX_VALUE;	// 从a[i]加到a[j]的值 与 目标值的差
for(int i =0; i < Sum.length; i++){
    寻找Sum数列中,第一个满足 Sum[j]-Sum[i]>=target 的 j
    与此同时,要记录下这个j所算得的 Sum[j]-Sum[i] 距离 target 的距离,如果比当前的 min 小,就替换掉它
}
最后输出所有的 Sum[j]-Sum[i]-target==min 的i和j
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章