【PAT甲级 - C++题解】1079 Total Sales of Supply Chain

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

1079 Total Sales of Supply Chain

A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone involved in moving a product from supplier to customer.

Starting from one root supplier, everyone on the chain buys products from one’s supplier in a price P and sell or distribute them in a price that is r% higher than P. Only the retailers will face the customers. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.

Now given a supply chain, you are supposed to tell the total sales from all the retailers.

Input Specification:

Each input file contains one test case. For each case, the first line contains three positive numbers: N (≤105), the total number of the members in the supply chain (and hence their ID’s are numbered from 0 to N−1, and the root supplier’s ID is 0); P, the unit price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then N lines follow, each describes a distributor or retailer in the following format:

K i K_i Ki ID[1] ID[2] … ID[ K i K_i Ki]

where in the i-th line, K i K_i Ki is the total number of distributors or retailers who receive products from supplier i, and is then followed by the ID’s of these distributors or retailers. K j K_j Kj being 0 means that the j-th member is a retailer, then instead the total amount of the product will be given after K j K_j Kj . All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the total sales we can expect from all the retailers, accurate up to 1 decimal place. It is guaranteed that the number will not exceed 1010.

Sample Input:

10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3

Sample Output:

42.4
题意

供应链是由零售商,经销商和供应商构成的销售网络,每个人都参与将产品从供应商转移到客户的过程。

整个销售网络可以看作一个树形结构,从根部的供应商往下,每个人从上一级供应商中买入商品后,假定买入价格为 P ,则会以高出买入价 r% 的价格向下出售。

只有零售商(即叶节点)可以直接将产品销售给顾客。

现在,给定整个销售网络,请你计算所有零售商的总销售额。

第一行包含三个数,N 表示供应链总成员数(所有成员编号从 0N−1 ,根部供应商编号为 0 ),P 表示根部供应商的每件产品的售卖价格,r ,溢价百分比。

接下来 N 行,每行包含一个成员的信息,格式如下:

Ki ID[1] ID[2] … ID[Ki]

其中第 i 行,Ki 表示从供应商 i 直接进货的成员数,接下来 Ki 个整数是每个进货成员的编号。

如果某一行的 Kj0 ,则表示这是零售商,那么后面只会跟一个数字,表示卖给客户的产品总件数。

思路
  1. 我们可以存储每个结点的父结点,另外零售商的数值需要额外存储即当 k0 的时候。
  2. 通过树形 DP 来计算树的深度,用一个 f 数组来存储每次计算的值,这样就可以排除重复计算的步骤。
  3. 计算总销售额时只用判断每次遍历的结点是否为叶子结点即可,然后通过公式 c[i] * P * pow(1 + R / 100, dfs(i)) 计算该叶子结点即零售商的销售额。其中 c[i] 表示该销售商卖给客户的产品总件数,P 表示产品的单位价格,pow(1 + R / 100, dfs(i)) 则是计算 1 + R/100dfs(i) 次方即每多一层关系次方数就加 1
  4. 输出最终结果,注意结果只取小数点后一位。
代码
#include<bits/stdc++.h>
using namespace std;

const int N = 100010;
int n;
double P, R;
int p[N], c[N], f[N];

//树形DP,记忆化搜索
int dfs(int u)
{
    //剪枝,如果f[u]已经被计算过,直接返回即可
    if (f[u] != -1)    return f[u];
    //如果该结点没有父结点,直接返回0,同时更新f[u]
    if (p[u] == -1)    return f[u] = 0;
    return f[u] = dfs(p[u]) + 1;
}

int main()
{
    cin >> n >> P >> R;

    //输入结点信息,存储每个结点的父结点
    memset(p, -1, sizeof p);
    for (int i = 0; i < n; i++)
    {
        int k;
        cin >> k;
        for (int j = 0; j < k; j++)
        {
            int id;
            cin >> id;
            p[id] = i;    //记录供应商是谁
        }
        if (!k)  cin >> c[i]; //如果是零售商,则另外存储
    }

    memset(f, -1, sizeof f);

    //计算总销售额
    double res = 0;
    for (int i = 0; i < n; i++)
        if (c[i])
            res += c[i] * P * pow(1 + R / 100, dfs(i));

    printf("%.1lf\n", res);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:这段代码是一个解决LeetCode上某个题目的C++实现,具体是一个双指针的解法。该题目是计算一个数组中的积水量。代码中使用了两个指针分别指向数组的左右边界,然后通过比较左右指针所指向的元素的大小,来确定当前位置的积水量。具体的计算方法是,如果左指针所指向的元素小于右指针所指向的元素,则对左指针的左边进行操作,如果左指针所指向的元素大于等于右指针所指向的元素,则对右指针的右边进行操作。在每一次操作中,都会更新左边的最大值和右边的最大值,并计算当前位置的积水量。最后返回总的积水量。\[1\] 引用\[2\]:这段代码是另一个解决LeetCode上某个题目的C++实现,具体是一个深度优先搜索的解法。该题目是计算一个二维网格中从起点到终点的可行路径数量。代码中使用了递归的方式进行深度优先搜索,从起点开始,每次向下或向右移动一步,直到到达终点。在每一步移动中,会判断当前位置是否有障碍物,如果有障碍物则返回0,如果到达终点则返回1,否则继续递归搜索下一步的位置。最后返回总的可行路径数量。\[2\] 引用\[3\]:这段代码是另一个解决LeetCode上某个题目的C++实现,具体是一个动态规划的解法。该题目是计算一个数组中的积水量。代码中使用了动态规划的思想,通过遍历数组中的每个元素,分别计算该元素左边和右边的最大值,并计算当前位置的积水量。最后返回总的积水量。\[3\] 综上所述,这三段代码分别是解决LeetCode上不同题目的C++实现,分别使用了双指针、深度优先搜索和动态规划的方法来解决问题。 #### 引用[.reference_title] - *1* *3* [Leetcode 热题100 42.接雨水(C++ 多种解法,错过可惜)](https://blog.csdn.net/qq_51933234/article/details/124637883)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [[C++]Leetcode 不同路径 || 解题思路及详解](https://blog.csdn.net/weixin_62712365/article/details/123951736)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值