【PAT甲级 - C++题解】1106 Lowest Price in Supply Chain

简介: 【PAT甲级 - C++题解】1106 Lowest Price in Supply Chain

1106 Lowest Price in 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 lowest price a customer can expect from some retailers.

Input Specification:


6.png

Output Specification:


For each test case, print in one line the lowest price we can expect from some retailers, accurate up to 4 decimal places, and the number of retailers that sell at the lowest price. There must be one space between the two numbers. It is guaranteed that the all the prices will not exceed 1010.

Sample Input:

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


Sample Output:

1.8362 2


题意


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


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


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


现在,给定整个销售网络,输出零售商可达到的最低销售价格,保留四位小数,以及可达到最低销售价格的零售商的数量。


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


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

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

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

如果某一行的 Kj0 ,则表示这是零售商。



思路


我们可以用一个数组 p 来存储每个结点的父结点,并且再用一个数组 is_leaf 来判断每个结点是否是叶子结点。另外,当 k 为 0 时,代表该结点是根供应商。

通过树形 DP 来计算树的深度,用一个 f 数组来存储每次计算的值,这样就可以排除重复计算的步骤。

计算总销售额时只用判断每次遍历的结点是否为叶子结点即可,然后通过公式 P * pow(1 + R / 100, dfs(i)) 计算该叶子结点即零售商的销售额。其中,P 表示产品的单位价格,pow(1 + R / 100, dfs(i)) 则是计算 1 + R/100 的 dfs(i) 次方即每多一层关系次方数就加 1 。每次计算完之后,再去判断当前深度是否是最小值(因为价格是固定的,所以深度越小的零售商的销售额越小),如果是最小值则更新答案,如果等于最小值则最小销售额的销售商数量加 1 。

输出最终结果,注意销售额最小值保留四个小数点。

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
double P, R;
int p[N], f[N];
bool is_leaf[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 son;
            cin >> son;
            p[son] = i;   //记录父结点是谁
        }
        if (!k)  is_leaf[i] = true;
    }
    memset(f, -1, sizeof f);
    //找到从根结点到叶子结点最短的深度
    int res = n, cnt = 0;
    for (int i = 0; i < n; i++)
        if (is_leaf[i])
        {
            if (dfs(i) < res)  res = dfs(i), cnt = 1;
            else if (dfs(i) == res)    cnt++;
        }
    printf("%.4lf %d\n", P * pow(1 + R / 100, res), cnt);
    return 0;
}
目录
相关文章
|
C++
【PAT甲级 - C++题解】1040 Longest Symmetric String
【PAT甲级 - C++题解】1040 Longest Symmetric String
73 0
|
算法 C++
【PAT甲级 - C++题解】1044 Shopping in Mars
【PAT甲级 - C++题解】1044 Shopping in Mars
94 0
|
C++
【PAT甲级 - C++题解】1117 Eddington Number
【PAT甲级 - C++题解】1117 Eddington Number
85 0
|
5天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
43 18
|
5天前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
31 13
|
5天前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
21 5
|
5天前
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
20 5
|
5天前
|
Serverless 编译器 C++
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
本任务要求设计一个矩形类、圆形类和图形基类,计算并输出相应图形面积。相关知识点包括纯虚函数和抽象类的使用。 **目录:** - 任务描述 - 相关知识 - 纯虚函数 - 特点 - 使用场景 - 作用 - 注意事项 - 相关概念对比 - 抽象类的使用 - 定义与概念 - 使用场景 - 编程要求 - 测试说明 - 通关代码 - 测试结果 **任务概述:** 1. **图形基类(Shape)**:包含纯虚函数 `void PrintArea()`。 2. **矩形类(Rectangle)**:继承 Shape 类,重写 `Print
22 4
|
5天前
|
设计模式 IDE 编译器
【C++面向对象——类的多态性与虚函数】编写教学游戏:认识动物(头歌实践教学平台习题)【合集】
本项目旨在通过C++编程实现一个教学游戏,帮助小朋友认识动物。程序设计了一个动物园场景,包含Dog、Bird和Frog三种动物。每个动物都有move和shout行为,用于展示其特征。游戏随机挑选10个动物,前5个供学习,后5个用于测试。使用虚函数和多态实现不同动物的行为,确保代码灵活扩展。此外,通过typeid获取对象类型,并利用strstr辅助判断类型。相关头文件如&lt;string&gt;、&lt;cstdlib&gt;等确保程序正常运行。最终,根据小朋友的回答计算得分,提供互动学习体验。 - **任务描述**:编写教学游戏,随机挑选10个动物进行展示与测试。 - **类设计**:基类
19 3
|
2月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
69 2