[code] PTA 胡凡算法笔记 DAY009

本文深入解析了四个经典算法竞赛题目,包括成绩计算、赛事投注策略、签到签退记录分析及性别成绩对比,提供了C++实现代码,强调了中间数据处理与结果直接输出的优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目 B1032 挖掘机技术哪家强

在这里插入图片描述

  • 题意
    计算输出总和最大的成绩信息。

  • 思路
    因为这里学校编号是连续的,所以可以考虑用数组下标和作为学校编号,然后在输入的时候边输入边计算,用一个变量去记录最大成绩的学校编号即可。因为成绩在后面还会使用,所以这里需要申请数组保存中间结果。

  • Code in C++

#include <iostream>

#define maxn 100001
int grades[maxn] = {0};

int main()
{
    int maxIndex = 0;
    int N;
    std::cin >> N;
    while (N--) {
        int index, grade;
        std::cin >> index >> grade;
        grades[index] += grade;
        if (grades[maxIndex] < grades[index]) {
            maxIndex = index;
        }
    }
    std::cout << maxIndex << " " << grades[maxIndex] << std::endl;
    return 0;
}

题目 A1011 World Cup Betting

在这里插入图片描述

  • 题意
    按公式计算结果,(max_1 * max_2 * max_3 * 0.65 - 1 ) * 2 ,并记录每次选择max_i对应的结果。

  • 思路
    W,T,L可以用数组作为映射,然后在输入的过程中可以不断去更新最大取值以及押的结果。
    优化:这里其实押的结果没必要记录下来可以直接输出。

  • Code in C++

#include <iostream>

struct result {
    int results[3];
    double profits;
};
int main()
{
    char tables[3] = {'W', 'T', 'L'};
    double odds[3][3];
    result ret;
    ret.profits = 1.0;
    for (int i = 0; i < 3; ++i) {
        double tmp = 0.0;
        for (int j = 0; j < 3; ++j) {
            std::cin >> odds[i][j];
            if (odds[i][j] > tmp) {
                ret.results[i] = j;
                tmp = odds[i][j];
            }
        }
        ret.profits *= odds[i][ret.results[i]];
    }

    ret.profits = (ret.profits * 0.65 - 1 ) * 2;
    printf("%c %c %c %.2f\n", tables[ret.results[0]], tables[ret.results[1]], tables[ret.results[2]], ret.profits);

    return 0;
}

题目 A1006 Sign In and Sign Out

在这里插入图片描述

  • 题意
    记录最早到的学生ID以及最晚离开的学生ID并输出。

  • 思路
    这里时间是按给定格式输入的,一样可以用字符串的大小去判断。在输入的过程中去更新最早时间(初值为:24:00:00)和最晚时间(初值为00:00:00)。

  • Code in C++

#include <iostream>
#include <string>

int main()
{
    std::string lockID, unlockID;
    std::string firstTime = "24:00:00", lastTime = "00:00:00";
    std::string ID, inTime, outTime;
    int M;

    std::cin >> M;
    while (M--) {
        std::cin >> ID >> inTime >> outTime;
        if (inTime < firstTime) {
            firstTime = inTime;
            unlockID = ID;
        }
        if (outTime > lastTime) {
            lastTime = outTime;
            lockID = ID;
        }
    }

    std::cout << unlockID << " " << lockID << std::endl;

    return 0;
}

题目 A1036 Boys vs Girls

在这里插入图片描述

  • 题意
    获取女生最高成绩与男生最低成绩学生信息,并输出成绩差。没有情况输出Absent成绩差输出NA

  • 思路
    首先,没必要保留输入成绩信息,所以只要临时变量存储即可。其次,因为成绩是0-100的整数,所以女生初始化成绩可以设为-1,男生设为101,这样不仅可以便于更新也可以用于判断是否存在。

  • Code in C++

#include <iostream>
#include <string>

struct info {
    std::string name;
    std::string ID;
    int grade;
} maxFe, minMa;

int main()
{
    maxFe.grade = -1;
    minMa.grade = 101;
    int N;
    std::cin >> N;
    while (N--) {
        std::string tm_name, tm_ID;
        char gender;
        int grade;
        std::cin >> tm_name >> gender >> tm_ID >> grade;
        if (gender == 'F' && grade > maxFe.grade ) {
            maxFe.name = tm_name;
            maxFe.ID = tm_ID;
            maxFe.grade = grade;
        }
        if (gender == 'M' && grade < minMa.grade) {
            minMa.name = tm_name;
            minMa.ID = tm_ID;
            minMa.grade = grade;
        }
    }

    if (maxFe.grade != -1) {
        std::cout << maxFe.name << " " << maxFe.ID << std::endl;
    } else {
        std::cout << "Absent" << std::endl;
    }

    if (minMa.grade != 101) {
        std::cout << minMa.name << " " << minMa.ID << std::endl;
    } else {
        std::cout << "Absent" << std::endl;
    }

    if (maxFe.grade != -1 && minMa.grade != 101) {
        std::cout << maxFe.grade - minMa.grade << std::endl;
    } else {
        std::cout << "NA" << std::endl;
    }

    return 0;
}

小结

  1. 思考中间的输入数据是否需要保存。
  2. 输出结果时是否可以直接输出无需保存。 @A1011
  3. 对于程序可能出现的结果要考虑全面(最后一题要是题目不说需要输出NA等,我估计自己做的时候根本都不会考虑不存在的情况)。

PS:学到了新单词tie平局;odd还有几率的意思。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值