当前位置: 首页 > article >正文

CE11.【C++ Cont】练习题组12(结构体专题)

目录

1.P5742【深基7.例11】评等级

题目

代码

提交结果

2.B2125 最高分数的学生姓名

题目

代码

方法1

提交结果

方法2:在方法1基础上改进

提交结果

​编辑 方法3:先排序后选,较麻烦

提交结果

​编辑

3.[NOIP2007 普及组] 奖学金

题目

错误代码

提交结果

调试分析

正确代码

提交结果


1.P5742【深基7.例11】评等级

题目

【深基7.例11】评等级 - 洛谷

题目描述

现有 N 名同学,每名同学需要设计一个结构体记录以下信息:学号、学业成绩和素质拓展成绩、综合分数(实数)。每行读入同学的学号、学业成绩和素质拓展成绩,并且计算综合分数(分别按照 70% 和 30% 权重累加),存入结构体中。还需要在结构体中定义一个成员函数,返回该结构体对象的学业成绩和素质拓展成绩的总分。

然后需要设计一个函数,其参数是一个学生结构体对象,判断该学生是否“优秀”。优秀的定义是学业和素质拓展成绩总分大于 140 分,且综合分数不小于 80 分。

当然通过本题很容易啦,本题只是为了帮助你训练结构体的使用方法。

本题存在精度误差问题,请将 a * 0.7 + b * 0.3 与 80 比较 转化为 a * 7 + b * 3 与 800 比较。

输入格式

第一行一个整数 N。

接下来 N 行,每行 3 个整数,依次代表学号、学业成绩和素质拓展成绩。

输出格式

N 行,如果第 i 名学生是优秀的,输出 Excellent,否则输出 Not excellent

输入输出样例

输入 #1

4
1223 95 59
1224 50 7
1473 32 45
1556 86 99

输出 #1

Excellent
Not excellent
Not excellent
Excellent

说明/提示

数据保证,1≤N≤1000,学号为不超过 100000 的正整数,学业成绩和素质拓展成绩为 0∼100 之间的正整数。

代码

本题较好考察了C24.【C++ Cont】结构体文章的知识点:成员函数的创建和调用

#include <iostream>
using namespace std;
struct Stu
{
	int id;
	int academic_score;//学业成绩
	int qual_dev_score;//素质拓展成绩
	double com_score;//综合成绩
	int add()
	{
		return academic_score+qual_dev_score;
	}
};
int  main()
{
	int n,i=0; 
	Stu s[1010];
	cin>>n;
	while(n--)
	{
		cin>>s[i].id>>s[i].academic_score>>s[i].qual_dev_score;
		s[i].com_score=0.7*s[i].academic_score+0.3*s[i].qual_dev_score;
		if ((s[i].add()>140)&&(7*s[i].academic_score+3*s[i].qual_dev_score)>=800)
			cout<<"Excellent"<<endl;
		else
			cout<<"Not excellent"<<endl;
		i++;
	}
	return 0;
}

提交结果

2.B2125 最高分数的学生姓名

题目

最高分数的学生姓名 - 洛谷

题目描述

输入学生的人数,然后再输入每位学生的分数和姓名,求获得最高分数的学生的姓名。

输入格式

第一行输入一个正整数 N(N≤100),表示学生人数。

接着输入 N 行,每行包括一个整数和一个字符串,用空格分开,代表分数姓名。

分数是一个非负整数,且小于等于 100;

姓名为一个连续的字符串,中间没有空格,长度不超过 20。

数据保证所有同学的姓名都不同,而且最高分只有一位同学。

输出格式

获得最高分数同学的姓名。

输入输出样例

输入 #1

5
87 lilei
99 hanmeimei
97 lily
96 lucy
77 jim

输出 #1

hanmeimei

说明/提示

hanmeimei 的分数最高 99 分。

限制:使用结构体解决

代码

方法1

#include <iostream>
using namespace std;
struct Stu
{
	int score;
	string name;
};

int  main()
{
	int n,highest_score=-1;
	int index=0;
	Stu s[110];
	cin>>n;
	n--;
	while(n--)
	{
		cin>>s[n].score>>s[n].name;
		if (s[n].score>highest_score)
		{
			index=n;
			highest_score=s[n].score;
		}
	}
	cout<<s[index].name;
	return 0;
}

提交结果

方法2:在方法1基础上改进

其实没有必要开辟那么多空间(Stu s[110];),题目只要求输出最高分数的学生姓名,因此只需要Stu s={-1,""};即可!!!

#include <iostream>
using namespace std;
struct Stu
{
	int score;
	string name;
};

int  main()
{
	int n,highest_score=-1;
	string name; 
	Stu s={0,""};
	cin>>n;
	n--;
	while(n--)
	{
		cin>>s.score>>s.name;
		if (s.score>highest_score)
		{
			highest_score=s.score;
			name=s.name; 
		}
	}
	cout<<name;
	return 0;
}

提交结果

 方法3:先排序后选,较麻烦

#include <iostream>
#include <algorithm>
using namespace std;
struct Stu
{
	int score;
	string name;
};
bool cmp(struct Stu x,struct Stu y)
{
	return x.score>y.score;//排降序,最大值在s[0].score
}
int  main()
{
	int n,highest_score=-1;
	string name; 
	Stu s[110];
	cin>>n;
	for (int i=0;i<n;i++)
		cin>>s[i].score>>s[i].name;
	sort(&s[0],&s[n-1],cmp);
	cout<<s[0].name;
	return 0;
}

提交结果

3.[NOIP2007 普及组] 奖学金

题目

[NOIP2007 普及组] 奖学金 - 洛谷

题目背景

NOIP2007 普及组 T1

题目描述

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

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

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

7 279  
5 279

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

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

5 279  
7 279

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

输入格式

共 n+1 行。

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

第 2 到 n+1 行,每行有 33 个用空格隔开的数字,每个数字都在 00 到 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

错误代码

读题后,每个学生的信息需要用一个结构体存储

#include <iostream>
#include <algorithm>
using namespace std;
struct Stu
{
	int id;
	int chinese;
	int math;
	int english;
	int all;
}s[310];
bool cmp_by_chinese(struct Stu x,struct Stu y);
bool cmp_by_id(struct Stu x,struct Stu y); 
bool cmp_by_all(struct Stu x,struct Stu y)
{
	return x.all>y.all;
}

bool cmp_by_chinese(struct Stu x,struct Stu y)
{
	return (x.chinese>y.chinese) && (x.all==y.all);
} 

bool cmp_by_id(struct Stu x,struct Stu y)
{
	return (x.id<y.id) && (x.chinese==y.chinese) && (x.all==y.all);
} 

int  main()
{
	int n;
	cin>>n;
	for (int i=1;i<n+1;i++)
	{
		s[i].id=i;
		cin>>s[i].chinese>>s[i].math>>s[i].english;
		s[i].all=s[i].chinese+s[i].english+s[i].math;
	}	
	
	sort(&s[1],&s[n+1],cmp_by_all);
    sort(&s[1],&s[n+1],cmp_by_chinese);
    sort(&s[1],&s[n+1],cmp_by_id);

	if (n>=5)
	{
		for (int i=1;i<6;i++)
		{
			cout<<s[i].id<<" "<<s[i].all<<endl;
		}
	}
	else
	{
		for (int i=1;i<n+1;i++)
		{
			cout<<s[i].id<<" "<<s[i].all<<endl;
		}	
	} 
	return 0;
}

提交结果

调试分析

错误代码犯了严重的错误,借用luogu平台提供的第6个测试用例使用VS2022调试

 附:luogu平台提供的第6个测试用例下载链接:百度网盘 请输入提取码
提取码: yt6m

 先在三个sort函数和if判断处下断点,之后调试

打开监视窗口,输入s查看

 执行sort(&s[1],&s[n+1],cmp_by_chinese);后发现排名第一的all==276被all==201所替代了

 

cmp_by_chinese的条件写错了,不能返回 (x.chinese>y.chinese) && (x.all==y.all);逻辑结果

条件1条件2结果(true或false)
x.chinese>y.chinesex.all>y.allfalse(需要交换x和y)
x.chinese>y.chinesex.all==y.alltrue(不需要交换x和y)
x.chinese>y.chinesex.all<y.allfalse(需要交换x和y)
x.chinese==y.chinesex.all>y.allfalse(需要交换x和y)
x.chinese==y.chinesex.all==y.allfalse(需要交换x和y)
x.chinese==y.chinesex.all<y.allfalse(需要交换x和y)
x.chinese<y.chinesex.all>y.allfalse(需要交换x和y)
x.chinese<y.chinesex.all==y.allfalse(需要交换x和y)
x.chinese<y.chinesex.all<y.all

false(需要交换x和y)

选一行看

x.chinese>y.chinesex.all>y.allfalse(需要交换x和y)

明明x的总分大于y,为什么还要交换x和y?不符合规则,应该写成if判断的形式

正确代码

#include <iostream>
#include <algorithm>
using namespace std;
struct Stu
{
	int id;
	int chinese;
	int math;
	int english;
	int all;
}s[310];
bool cmp_by_chinese(struct Stu x,struct Stu y);
bool cmp_by_id(struct Stu x,struct Stu y);
bool cmp_by_all(struct Stu x,struct Stu y)
{
	if (x.all>y.all||x.all<y.all)
		return x.all>y.all;
	else
		return cmp_by_chinese(x,y);//一定要写return,否则会报段错误
	
}

bool cmp_by_chinese(struct Stu x,struct Stu y)
{
	if (x.chinese>y.chinese || x.chinese<y.chinese)
		return x.chinese>y.chinese;
	else return cmp_by_id(x,y););//一定要写return,否则会报段错误
} 

bool cmp_by_id(struct Stu x,struct Stu y)
{
	return x.id<y.id;
} 

int  main()
{
	int n;
	cin>>n;
	for (int i=1;i<n+1;i++)
	{
		s[i].id=i;
		cin>>s[i].chinese>>s[i].math>>s[i].english;
		s[i].all=s[i].chinese+s[i].english+s[i].math;
	}	
	
	sort(&s[1],&s[n+1],cmp_by_all);
	if (n>=5)
	{
		for (int i=1;i<6;i++)
		{
			cout<<s[i].id<<" "<<s[i].all<<endl;
		}
	}
	else
	{
		for (int i=1;i<n+1;i++)
		{
			cout<<s[i].id<<" "<<s[i].all<<endl;
		}	
	} 
	return 0;
}

其实没有必要用三个cmp函数,可以这样写:

bool cmp_by_all(struct Stu x,struct Stu y)
{
	if (x.all!=y.all)
		return x.all>y.all;
	else if  (x.chinese!=y.chinese)
		return x.chinese>y.chinese;
	else  return x.id<y.id;
}

提交结果


http://www.kler.cn/a/525997.html

相关文章:

  • 探索AI(chatgpt、文心一言、kimi等)提示词的奥秘
  • vim操作简要记录
  • 不背单词快捷键(不背单词键盘快捷键)
  • 【C语言练习题】整数和实数在计算机中的二进制表示
  • 51单片机开发:串口通信
  • SpringBoot中@Valid与@Validated使用场景详解
  • MATLAB中textBoundary函数用法
  • 在godot中接入大模型api,实现npc的自动对话
  • 如何使用Python调用大语言模型的API接口?
  • 【单细胞第二节:单细胞示例数据分析-GSE218208】
  • 改进候鸟优化算法之五:基于多目标优化的候鸟优化算法(MBO-MO)
  • C++ 继承和多态
  • Docker小游戏 | 使用Docker部署FC-web游戏模拟器
  • 顺启逆停程序
  • cursor软件的chat和composer分别是什么
  • 9 Spark性能优化_RDD算子调优
  • 再谈多组学(multi-omics)
  • Cloudreve:Star22.3k,免费开源的网盘,支持多种存储方式,它允许用户快速搭建个人或团队的私有云存储服务。
  • 数据结构与算法学习笔记----容斥原理
  • 基于Java+Swing实现推箱子游戏
  • [Effective C++]条款49-52 内存分配
  • Linux运维之Linux的安装和配置
  • 我的2024年博客总结(在工作、博客和生活中找到自己的生活节奏)
  • 创建前端项目的方法
  • Baklib引领内容管理平台新时代优化创作流程与团队协作
  • ARM嵌入式学习--第十天(UART)