2021 年 6 月青少年软编等考 C 语言五级真题解析

T1. 圣诞老人的礼物

题目链接:SOJ D1083

圣诞节来临了,在城市 A 中圣诞老人准备分发糖果,现在有多箱不同的糖果,每箱糖果有自己的价值和重量,每箱糖果都可以拆分成任意散装组合带走。圣诞老人的驯鹿最多只能承受一定重量的糖果,请问圣诞老人最多能带走多大价值的糖果。

时间限制:1 s
内存限制:64 MB

  • 输入
    第一行由两个部分组成,分别为糖果箱数正整数 n   ( 1 ≤ n ≤ 100 ) n\ (1\le n\le 100) n (1n100),驯鹿能承受的最大重量正整数 w   ( 0 < w < 10000 ) w\ (0 < w < 10000) w (0<w<10000),两个数用空格隔开。其余 n n n 行每行对应一箱糖果,由两部分组成,分别为一箱糖果的价值正整数 v v v 和重量正整数 w w w,中间用空格隔开。
  • 输出
    输出圣诞老人能带走的糖果的最大总价值,保留 1 1 1 位小数。输出为一行,以换行符结束。
  • 样例输入
    4 15
    100 4
    412 8
    266 7
    591 2
    
  • 样例输出
    1193.0
    

思路分析

此题考查贪心算法中的部分背包问题,属于基础题。

由于糖果可以拆分,因此背包必定可以装满。要想最终总价值最大,容易想到优先装入性价比最高的糖果,每一步决策后的结果都是当前最优解。

可以采用反证法证明该策略的正确性,即假设该策略不是最优的,那么优先装入性价比较低的糖果:

  • 在同等重量下,新策略可以获得的总价值并非当前最优;
  • 在同等价值下,新策略的糖果总重量更重,那么后续选择的冗余空间更小,不能使结果更优,甚至可能变劣。

因此新策略并非最优解,原策略是为最优解。

在代码实现时,按照性价比降序排序,之后依次遍历每一种糖果,在可以装完的情况下就全部装入,否则选取一部分将剩余空间装满即可。在此过程中,依次按照装入比例累加糖果总价值即可。

/*
 * Name: T1.cpp
 * Problem: 圣诞老人的礼物
 * Author: Teacher Gao.
 * Date&Time: 2025/01/03 19:27
 */

#include <iostream>
#include <iomanip>
#include <algorithm>

using namespace std;

struct candy {
   
    int v, w;
    bool operator<(const candy& a) const {
   
        return v*a.w > a.v*w;
    }
} a[105];

int main()
{
   
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, w;
    cin >> n >> w;
    for (int i = 1; i <= n; i++)
        cin >> a[i].v >> a[i].w;

    sort(a + 1, a + n + 1);
    double sum = 0;
    for (int i = 1; i <= n; i++) {
   
        if (a[i].w <= w) {
   
            sum += a[i].v;
            w -= a[i].w;
        }
        else {
   
            sum += 1.0 * a[i].v / a[i].w * w;
            break;
        }
    }

    cout << fixed << setprecision(1) << sum << endl;

    return 0;
}

T2. 数字变换

题目链接:SOJ D1084

给定一个包含 5 5 5 个数字( 0 ∼ 9 0\sim 9 09)的字符串,例如 "02943",请将 "12345" 变换到它。你可以采取 3 3 3 种操作进行变换

  1. 交换相邻的两个数字;
  2. 将一个数字加 1 1 1。如果加 1 1 1 后大于 9 9 9,则变为 0 0 0
  3. 将一个数字加倍。如果加倍后大于 9 9 9,则将其变为加倍后的结果除以 10 10 10 的余数。

最多只能用第 2 2 2 种操作 3 3 3 次,第 3 3 3 种操作 2 2 2 次,求最少经过多少次操作可以完成变换。

时间限制:1 s
内存限制:64 MB

  • 输入
    有最多 1 0 5 10^5 105 组数据,每组数据就是包含 5 5 5 个数字的字符串。
  • 输出
    对每组数据,输出将 "12345" 变换到给定字符串所需要的最少操作步数。如果无法变换成功,输出 − 1 -1 1
  • 样例输入
    12435
    99999
    12374
    
  • 样例输出
    1
    -1
    3
    
  • 提示
    由于测试数据太多,如果对每组数据都从头进行搜索,就会超时。建议先做预处理,即以 "12345" 作为初始状态做一遍彻底的广搜,找出 "12345" 经合法变换能够到达的所有字符串,并记录到达这些字符串各需要多少步操作。然后对读入的每组数据,在上述预处理记录的结果中进行查询即可。

思路分析

此题考查 B F S \tt BFS BFS,有一定难度。

根据题目的提示信息,我们需要用 B F S \tt BFS BFS 预处理出所有数字串对应的答案。为了便于标记状态,定义

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南朔 Clancy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值