HDU1084——What Is Your Grade?,HDU1085——Holding Bin-Laden Captive!(母函数的运用)

目录

HDU1084——What Is Your Grade?

题目描述

运行代码

代码思路

HDU1085——Holding Bin-Laden Captive!

题目描述

运行代码

代码思路

母函数

HDU1084——What Is Your Grade?

题目描述

Problem - 1084

运行代码

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

class Stu {
public:
    int sol;
    int tim;
    int id;
    int sco;
};

int divi(int g) {
    if (g == 1) {
        return 1;
    }
    else {
        return g / 2;
    }
}

int timConv(string tar) {
    int h, m, s;
    sscanf_s(tar.c_str(), "%d:%d:%d", &h, &m, &s);
    return h * 3600 + m * 60 + s;
}

bool cmpf(Stu c1, Stu c2) {
    if (c1.sol != c2.sol) {
        return c1.sol > c2.sol;
    }
    else {
        return c1.tim < c2.tim;
    }
}

bool cmpf2(Stu c1, Stu c2) {
    return c1.id < c2.id;
}

int main() {
    Stu cls[109];
    int cnts[6];
    int num;
    while (cin >> num && num != -1) {
        fill(cnts, cnts + 6, 0);
        string tar;
        for (int i = 0; i < num; i++) {
            cin >> cls[i].sol >> tar;
            cls[i].tim = timConv(tar);
            cls[i].sco = cls[i].sol * 10 + 50;
            cls[i].id = i;
            cnts[cls[i].sol]++;
        }

        sort(cls, cls + num, cmpf);

        int pos = cnts[5];
        for (int n = 4; n >= 1; n--) {
            for (int i = pos; i < pos + divi(cnts[n]); i++) {
                cls[i].sco += 5;
            }
            pos += cnts[n];
        }
        sort(cls, cls + num, cmpf2);
        for (int i = 0; i < num; i++) {
            cout << cls[i].sco << endl;
        }
        cout << endl;
    }
    return 0;
}

代码思路

  1. 定义了一个 Stu 类,包含了学生解决问题的数量 sol、花费的时间 tim、索引 id 和最终的分数 sco 。

  2. divi 函数用于根据输入的整数计算其一半的值(对于 1 则返回 1)。

  3. timConv 函数用于将输入的时间字符串(格式为 hh:mm:ss )转换为秒数。

  4. cmpf 函数用于比较两个 Stu 对象,首先比较解决问题的数量,如果数量相同则比较花费的时间,用于后续的排序。

  5. cmpf2 函数用于根据 Stu 对象的索引进行比较,用于另一种排序需求。

  6. 在 main 函数中:

    • 定义了 Stu 类型的数组 cls 来存储学生的信息,以及整数数组 cnts 来统计每个解决问题数量的学生数量。
    • 通过一个循环读入每个学生解决的问题数量和时间,并计算其初始分数,同时更新相应解决问题数量的学生数量统计。
    • 对 cls 数组按照解决问题数量和时间进行排序。
    • 计算每个解决问题数量的前半部分学生的位置,并给这些学生的分数增加 5 分。
    • 再次对 cls 数组按照索引进行排序。
    • 最后输出每个学生的最终分数,并在每个测试用例结束后输出一个空行。

HDU1085——Holding Bin-Laden Captive!

题目描述

Problem - 1085

运行代码

#include <iostream>
#include <cstring>
using namespace std;

const int maxn = 8050;
int c1[maxn], c2[maxn];

int main() {
    int coin[3] = { 1, 2, 5 };
    int num[4];
    while (cin >> num[0] >> num[1] >> num[2] && (num[0] != 0 || num[1] != 0 || num[2] != 0)) {
        int n = num[0] * 1 + num[1] * 2 + num[2] * 5;
        memset(c2, 0, sizeof(c2));
        memset(c1, 0, sizeof(c1));
        for (int i = 0; i <= num[0]; i++) {
            c1[i] = 1;
        }
        for (int i = 2; i <= 3; i++) {
            for (int j = 0; j <= n; j++) {
                for (int k = 0; k + j <= n && k / coin[i - 1] <= num[i - 1]; k += coin[i - 1])
                    c2[j + k] += c1[j];
            }
            for (int j = 0; j <= n; j++) {
                c1[j] = c2[j];
                c2[j] = 0;
            }
        }
        for (int i = 0; i <= n + 1; i++) {
            if (c1[i] == 0) {
                cout << i << endl;
                break;
            }
        }
    }
    return 0;
}

代码思路

  1. 首先定义了一些常量和数组:

    • maxn 表示一个较大的整数常量。
    • c1 和 c2 两个整数数组用于存储计算过程中的中间结果。
    • coin 数组存储了三种硬币的面值 {1, 2, 5} 。
  2. 在 main 函数中:

    • 定义了 num 数组用于接收用户输入的每种硬币的数量。
    • 通过一个 while 循环,不断读取用户输入的三种硬币的数量。如果三种硬币数量都为 0 ,则退出循环。
    • 计算总金额 n ,即每种硬币数量乘以其面值的总和。
    • 初始化 c1 数组,将前 num[0] 个位置的值设置为 1 。
    • 然后通过两个嵌套的循环进行计算:
      • 外层循环从 2 到 3 ,分别处理面值为 2 和 5 的硬币。
      • 内层的两个嵌套循环用于计算在当前面值硬币的情况下,能组成的各种金额的组合数,并累加到 c2 数组中。
    • 每次处理完一种面值的硬币后,将 c2 的值复制到 c1 ,并清空 c2 ,为下一种面值的硬币计算做准备。
    • 最后,通过一个循环找到第一个 c1 数组中值为 0 的位置 i ,输出 i 并结束循环。

母函数

函数(Generating function)是组合数学和数论中的一种强有力的工具,用于研究序列的性质。它是一种形式幂级数,通过将一个数列的项作为系数来构造。母函数可以用来解决计数问题、递推关系求解以及其他组合结构分析的问题。

母函数主要有两种类型:

母函数的优点在于,许多复杂的组合运算可以通过简单的代数运算在母函数上完成,比如加法、乘法等操作对应于数列的操作。例如,两个数列的卷积可以通过它们的母函数的乘积直接计算出来。

在实际应用中,通过适当的代数变换,我们往往可以从已知的简单母函数推导出更复杂数列的母函数,进而求解出数列的具体形式或者特定项的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

筱姌

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

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

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

打赏作者

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

抵扣说明:

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

余额充值