NOIP2007奖学金问题及简单背包问题

2024-03-30 18:20

本文主要是介绍NOIP2007奖学金问题及简单背包问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言:

最近刷了一些洛谷的基础算法题,关于排序类和贪心类,也发现了结构体用在这两种题目上的异曲同工之妙,那么我们废话不多说,直接上题目与解析帮助大家更好地掌握。

题目描述

某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前 55 名学生发奖学金。期末,每个学生都有 33 门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。

任务:先根据输入的 33 门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名名学生的学号和总分。

注意,在前 55 名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:

7 279  
5 279

这两行数据的含义是:总分最高的两个同学的学号依次是 77 号、55 号。这两名同学的总分都是 279279 (总分等于输入的语文、数学、英语三科成绩之和) ,但学号为 77 的学生语文成绩更高一些。

如果你的前两名的输出数据是:

5 279  
7 279

则按输出错误处理,不能得分。

输入格式

共 n+1 行。

第 1 行为一个正整数 n≤300,表示该校参加评选的学生人数。

第 2 到 n+1 行,每行有 3 个用空格隔开的数字,每个数字都在 0 到 100 之间。第 j 行的 3 个数字依次表示学号为 j−1 的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为 1∼n(恰好是输入数据的行号减 1)。

保证所给的数据都是正确的,不必检验。

输出格式

共 5行,每行是两个用空格隔开的正整数,依次表示前 5 名学生的学号和总分。

输入输出样例

输入 #1复制

6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98

输出 #1复制

6 265
4 264
3 258
2 244
1 237

输入 #2复制

8
80 89 89
88 98 78
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98

输出 #2复制

8 265
2 264
6 264
1 258
5 258

我们发现,排序的优先级是总分大的优先,总分相同则比较语文成绩,语文成绩相同则比较学号,学号小的同学排前面,这里需要注意,前面都是大的在前,唯有学号是小的在前,这是等下要编写的一个部分。

那我们来初步实现一下代码块:

代码块实现:

struct stu
{int num;int a,b,c;int sum;
}student[100005];

我们定义一个结构体部分负责接收学号,三科目成绩,总成绩等信息。

bool cmp(stu a,stu b)
{if(a.sum>b.sum){return 1;}else if(a.sum<b.sum){return 0;}else{if(a.y>b.y){return 1;}else if(a.y<b.y){return 0;}else{if(a.num<b.num){return 1;}else{return 0;}}}}

这里我们定义一个bool类型的比较函数,方便后续的排序中sort使用,我们依据推理逻辑,优先总分在先,再次语文,最后学号,注意是哪种情况该先排,哪种情况又该后排。

int main()
{int n;cin >> n;for(int i=1;i<=n;i++){student[i].num=i;cin >> student[i].yu >> student[i].shu >> student[i].eng;student[i].sum=student[i].yu+student[i].shu+student[i].eng;}sort(student+1,student+1+n,cmp);for(int i=1;i<=5;i++){cout << student[i].num << " " << student[i].sum << endl;}return 0;

这里是主函数的部分,注意结构体传数字时的操作,并使用sort根据上面的逻辑排序,最后输出即大功告成,这一题主要可以锻炼大家对于结构体与排序方法的掌握,很建议大家去做一下,最后完整代码和题目链接奉上:

#include <iostream>
#include <algorithm>
using namespace std;
struct stu
{int num;int yu,shu,eng;int sum;
}student[10005];
bool cmp(stu a,stu b)
{if(a.sum>b.sum){return 1;}else if(a.sum<b.sum){return 0;}else{if(a.yu>b.yu){return 1;}else if(a.yu<b.yu){return 0;}else{if(a.num>b.num){return 0;}else{return 1;}}}
}
int main()
{int n;cin >> n;for(int i=1;i<=n;i++){student[i].num=i;cin >> student[i].yu >> student[i].shu >> student[i].eng;student[i].sum=student[i].yu+student[i].shu+student[i].eng;}sort(student+1,student+1+n,cmp);for(int i=1;i<=5;i++){cout << student[i].num << " " << student[i].sum << endl;}return 0;
}

题目链接:https://www.luogu.com.cn/problem/P1093

部分背包问题:

在掌握了上一题之后,面对一部分的背包问题,我们是不是也可以使用异曲同工的方法来做出来呢?看下面这一题:

题目描述

阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有 N(N≤100) 堆金币,第 i 堆金币的总重量和总价值分别是 mi(1≤mi≤100),vi​​(1≤vi​≤100)。阿里巴巴有一个承重量为 (T≤1000) 的背包,但并不一定有办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里巴巴最多可以拿走多少价值的金币?

输入格式

第一行两个整数 N,T。

接下来 N 行,每行两个整数 mi​,vi​。

输出格式

一个实数表示答案,输出两位小数

输入输出样例

输入 #1复制

4 50
10 60
20 100
30 120
15 45

输出 #1复制

240.00

首先,题目很明确了我们可以分割单块金币,以获得权重最大的金币(权重=价值/质量),我们肯定优先选择相同质量价值最高的金币堆,那么我们就可以对权重进行排序,再慢慢比较背包质量与金币质量,直到背包刚好装满为止。

结构体定义:

struct value
{int w,v;double jun;
}money[100005];

再定义比较函数:

bool cmp(Value a,Value b)
{if(a.jun>b.jun){return 1;}else{return 0;}
}

主函数部分:

int main()
{int n,t;cin >> n >> t;for(int i=0;i<n;i++){cin >> money[i].w >> money[i].v;money[i].jun=money[i].v/money[i].w;}sort(money,money+n,cmp);double sum;for(int i=0;i<n;i++){if(t>money[i].w){sum+=money[i].v;t-=money[i].w;}else{sum+=t*money[i].jun;break;}}printf("%.2lf",sum);return 0;

这一题我觉得主函数部分是难于自定义函数部分的操作的,还有最后这一个break操作,一定要记得加上,也就是背包最后装块的部分,装了以后背包就满了。最后,完整代码和题目地址奉上:

#include <iostream>
#include <algorithm> 
using namespace std;
struct Value
{double w,v;double jun;
}money[10005];
bool cmp(Value a,Value b)
{if(a.jun>b.jun){return 1;}else{return 0;}
}
int main()
{int n,t;cin >> n >> t;for(int i=0;i<n;i++){cin >> money[i].w >> money[i].v;money[i].jun=money[i].v/money[i].w;}sort(money,money+n,cmp);double sum;for(int i=0;i<n;i++){if(t>money[i].w){sum+=money[i].v;t-=money[i].w;}else{sum+=t*money[i].jun;break;}}printf("%.2lf",sum);return 0;
}

题目链接:https://www.luogu.com.cn/problem/P2240

总结:

今天给大家介绍了两个题目,它们的布局大体相同,主要是为了大家能够掌握使用结构体,排序,自定义函数的结合使用来解决问题,制作不易,给个点赞鼓励一下吧!

这篇关于NOIP2007奖学金问题及简单背包问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/862231

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

Springboot如何正确使用AOP问题

《Springboot如何正确使用AOP问题》:本文主要介绍Springboot如何正确使用AOP问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录​一、AOP概念二、切点表达式​execution表达式案例三、AOP通知四、springboot中使用AOP导出

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

IDEA Maven提示:未解析的依赖项的问题及解决

《IDEAMaven提示:未解析的依赖项的问题及解决》:本文主要介绍IDEAMaven提示:未解析的依赖项的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录IDEA Maven提示:未解析的依编程赖项例如总结IDEA Maven提示:未解析的依赖项例如

Redis分片集群、数据读写规则问题小结

《Redis分片集群、数据读写规则问题小结》本文介绍了Redis分片集群的原理,通过数据分片和哈希槽机制解决单机内存限制与写瓶颈问题,实现分布式存储和高并发处理,但存在通信开销大、维护复杂及对事务支持... 目录一、分片集群解android决的问题二、分片集群图解 分片集群特征如何解决的上述问题?(与哨兵模

SpringBoot+Redis防止接口重复提交问题

《SpringBoot+Redis防止接口重复提交问题》:本文主要介绍SpringBoot+Redis防止接口重复提交问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录前言实现思路代码示例测试总结前言在项目的使用使用过程中,经常会出现某些操作在短时间内频繁提交。例