【PAT甲级 - C++题解】1044 Shopping in Mars

✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:PAT题解集合
📝原题地址:题目详情 - 1044 Shopping in Mars (pintia.cn)
🔑中文翻译:火星购物
📣专栏定位:为想考甲级PAT的小伙伴整理常考算法题解,祝大家都能取得满分!
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

1044 Shopping in Mars

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.

Input Specification:

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.

Output Specification:

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 + … + DjM) 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.

Sample Input 1:

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

Sample Output 1:

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

Sample Input 2:

5 13
2 4 5 7 9

Sample Output 2:

2-4
4-5
题意

给定 N 个数的序列 Di+…+Dj 和一个常量 M ,让我们输出所有区间和等于 M 的方案。

每行输出一种可行方案,具体格式为 i-j,表示 Di+…+Dj=M

如果方案不唯一,则按照 i 递增的顺序输出所有方案。

如果无法准确凑出 M ,仍然输出 i-j,表示 Di+…+Dj>M 并且 Di+…+Dj−M 的值最小。

如果方案不唯一,则按照 i 递增的顺序输出所有方案。

思路

这道题需要用到前缀和和双指针算法,先对序列求前缀和并存到数组 s 中。

然后先求大于等于M 的最小区间和 res ,因为可能不存在等于 M 的区间和。

最后再去遍历所有区间,输出所有等于 res 的区间和方案。

代码
#include<bits/stdc++.h>
using namespace std;

const int N = 100010, INF = 0x3f3f3f3f;
int s[N];
int n, m;

int main()
{
    scanf("%d%d", &n, &m);
    //求前缀和
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &s[i]);
        s[i] += s[i - 1];
    }

    //找到大于等于m的最小值
    int res = INF;
    for (int i = 1, j = 0; i <= n; i++)
    {
        //如果s[i]-s[j+1]>=m,则s[i]-s[j]也一定大于等于m,所以直接j++即可
        while (s[i] - s[j + 1] >= m)   j++;
        if (s[i] - s[j] >= m)    res = min(res, s[i] - s[j]);
    }

    //找到区间和等于res的所有方案
    for (int i = 1, j = 0; i <= n; i++)
    {
        while (s[i] - s[j + 1] >= m)   j++;
        if (s[i] - s[j] == res)  printf("%d-%d\n", j + 1, i);
    }

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值