结构体的晋升之路

一、长方形比大小

描述    

长方形家族有个很俗气的传统:谁大谁优先。 “比大小”的规则是:
1.面积大的优先
2.面积相同时,周长长的优先
请将n个长方形按“比大小”的规则排序后,输出每个长方形的序号。长方形的序号是1~n,和长方形的输入顺序一致。

输入描述

第1行,输入一个小于100的正整数,表示长方形的个数;
接下来的100行,每行输入一个长方形的长和宽(都是正整数),中间用单个空格隔开。

输出描述

输出n个正方形的序号。每个长方形占一行。

样例输入1


9 7
3 4
2 3
2 6
3 21
 

 样例输出1

5
1
4
2
3

 解题思路:

结构体排序时,先排特殊:满足面积相同排周长,再排普通:面积大优先

题解:

#include <bits/stdc++.h>
using namespace std;
//长方形结构体
struct rect{
	int id;//序号
	int s;//面积
	int c;//周长 
}re[105];
//定义排序规则
bool cmp(rect x,rect y){
	if(x.s==y.s) return x.c>y.c;
	else return x.s>y.s; 
} 
int n;//长方形个数 
int main() {
	cin>>n;
	for(int i = 1;i<=n;i++){
		int l,w;//长和宽
		cin>>l>>w;
		re[i].id = i;
		re[i].s = l*w;
		re[i].c = 2*(l+w);
	}
	//排序 
	sort(re+1,re+n+1,cmp);
	//输出 
	for(int i  = 1;i<=n;i++){
		cout<<re[i].id<<endl;
	}
  	return 0;
}

二、倒数第一名

描述

n名同学参加了英语考试。已知这n名学生的学号、姓名和成绩(0≤成绩≤100) ,请找出哪个学生是倒数第一名。当有多个学生是倒数第一名时,输出最先出现的那位。

输入描述

第1行一个正整数n,表示学生人数。(1<n<1000)
接下来n行,每行是一个学生的学号、姓名和成绩,用空格隔开。

输出描述

一行,倒数第一名的学生学号和姓名,用空格隔开。

样例输入1

5
1 haha 60
2 qiqi 72
3 yaya 80
4 lili 50
5 gege 50

样例输出1

4 lili

 题解:

#include <bits/stdc++.h>
using namespace std;
//学生结构体
struct student{
	int id;//学号 
	string name;//姓名 
	int score;//分数 
}stu[1005];
//定义排序规则
bool cmp(student x,student y){
	if(x.score == y.score)return x.id<y.id;
	else return x.score<y.score;
} 
int n;//n名学生 
int main() {
	cin>>n;
	for(int i = 1;i<=n;i++){
		cin>>stu[i].id>>stu[i].name>>stu[i].score;
	}
	sort(stu+1,stu+n+1,cmp);
	cout<<stu[1].id<<" "<<stu[1].name;
  	return 0;
}

三、马拉松比赛

描述

n个运动员参加马拉松比赛。输入每个选手的序号(序号是一个字符串)和成绩(跑完全程的分钟数,是个正整数),请将n个选手按如下规则排序后,输出运动员的序号。

  1. 成绩好的选手排前面;
  2. 成绩相同的选手,序号小的选手排前面。

输入描述

输入共有 n+1 行,第 1 行为运动员总人数 n;10 ≤n≤100000;
第 2 行至第 n+1 行分别是每人的序号和成绩,用空格隔开。

输出描述

输出共有 n 行,即排序完成后,n 个运动员从前往后的序号。

样例输入1

4
0001 224
0002 248
0003 220
0004 224

 样例输出1

0003
0001
0004
0002

 提示

 “成绩好的选手排前面”,意思是,用时少的选手排前面。也就是按成绩从小到大排序。

 题解

#include <bits/stdc++.h>
using namespace std;
//运动员结构体
struct player{
	string id;
	int grade;
}pl[100005]; 
//定义排序规则 
bool cmp(player x,player y){
	if(x.grade==y.grade) return x.id<y.id;
	else return x.grade<y.grade;
}
int n;//n名运动员 
int main() {
	cin>>n;
	for(int i = 1;i<=n;i++){
		cin>>pl[i].id>>pl[i].grade;
	}
	//sort排序
	sort(pl+1,pl+n+1,cmp);
	for(int i = 1;i<=n;i++){
		cout<<pl[i].id<<endl;
	} 
  	return 0;
}

四、生日

描述

小童知道CSP兴趣小组中每个同学的生日。于是,他想通过编程将小组成员按照年龄从大到小的顺序排序。但是小童编程水平又很菜,忙活了半天都没有实现自己的想法。请身为编程小能手的你,帮他完成排序。

输入描述

输入共有 n+1 行,第 1 行为 CSP兴趣小组总人数 n;
第 2 行至第 n+1 行分别是每个人的姓名 s、出生年 y、月 m、日 d。

输出描述

输出共有 n 行,即 n 个年龄从大到小同学的姓名。(任意两个同学的生日都不相同)。

样例输入1

3
yaya 2012 9 29
qiqi 2012 9 26
lili 2012 8 26

样例输出1

lili
qiqi
yaya

提示

1<n<100。保证年月日实际存在,且年份在1990~2022范围内。包括1990和2022。

题解

注意比年龄
1、出生年份大的反而小

2、年份相同,月份大的反而小

3、年月相同,日期大的反而小

#include <bits/stdc++.h>
using namespace std;
struct student{
	string name;
	int year;
	int month;
	int day;
}stu[105];
bool cmp(student x,student y){
	//如果年份相同 
	if(x.year == y.year){
		if(x.month==y.month) return x.day<y.day;
		else return x.month<y.month;
	}else{
		return x.year<y.year;
	}
}
int n;

int main() {
	cin>>n;
	for(int i = 1;i<=n;i++){
		cin>>stu[i].name>>stu[i].year>>stu[i].month>>stu[i].day;
	}
	sort(stu+1,stu+n+1,cmp);
	for(int i = 1;i<=n;i++){
		cout<<stu[i].name<<endl;
	}
  	return 0;
}

五、培训

描述

  • 姓名(字符串)
  • 年龄(周岁,整数)
  • 参加培训前的 CSP 成绩(整数,且保证是 5 的倍数)
    经过为期一年的培训,所有学员的成绩都提升了100分(当然 CSP 满分是 400 分,成绩不可能超过这个分数)。
    请设计一个结构体存储学生参加培训前的姓名、年龄和CSP成绩,并输出经过培训后,学员的姓名、年龄和最后成绩。

输入描述

第一行输入一个正整数 n,表示学员个数。
第二行开始往下 n 行。每行首先是一个字符串表示学员姓名,再是一个整数表示学员年龄,再是一个整数为参加培训前的CSP成绩。

输出描述

输出 n 行,每行首先输出一个字符串表示学生姓名,再往后两个整数,表示经过一年的培训后学员的年龄和他们今年的 NOIP 成绩。以空格隔开。

样例输入1

3
lili 9 10
yaya 10 200
lala 12 360

样例输出1

lili 10 110
yaya 11 300
lala 13 400

提示

1<n≤5000

题解

#include <bits/stdc++.h>
using namespace std;
struct student{
	string name;
	int age;
	int grade;
}stu[5005];
string na;
int a,g,n;
int main() {
	cin>>n;
	for(int i = 1;i<=n;i++){
		cin>>na>>a>>g;
		stu[i].name = na;
		stu[i].age = a + 1;
		stu[i].grade = ((g+100)>=400)?400:g+100;
	}
	for(int i = 1;i<=n;i++){
		cout<<stu[i].name<<" "<<stu[i].age<<" "<<stu[i].grade<<endl;
	}
  	return 0;
}

六、奖学金2

描述

某小学最近打算为学习成绩优秀的前 5 名学生发奖学金。每个学生都有 3 门课的成绩:语文、数学、英语(0≤各科成绩≤100)。
请根据下方的规则进行排序:
1、先按总分从高到低排序
2、如果两个同学总分相同,再按语文成绩从高到低排序
3、如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面。

最后按排名顺序输出前五名学生的学号和总分。

输入描述

第 1 行是一个正整数n (n≤300),表示该校参加评选的学生人数。
接下来的 n 行,每行有 3 个用空格隔开的整数,依次表示每个学生的语文、数学、英语的成绩。学生的学号按照输入顺序编号为 1∼n。

输出描述

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

样例输入1

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

样例输出1

8 265
2 264
6 264
5 258
1 258

题解 

#include <bits/stdc++.h>
using namespace std;
struct student{
	int sum;
	int yu;
	int id;
}stu[305];
bool cmp(student x,student y){
	if(x.sum==y.sum){
		if(x.yu==y.yu) return x.id<y.id;
		else return x.yu>y.yu; 
	}else{
		return x.sum>y.sum;
	}
}
int n;
int main() {
	cin>>n;
	int m,y,e;
	for(int i  = 1;i<=n;i++){
		cin>>y>>m>>e;
		stu[i].id = i;
		stu[i].yu = y;
		stu[i].sum = y+m+e; 
	}
	sort(stu+1,stu+n+1,cmp);
	for(int i = 1;i<=5;i++){
		cout<<stu[i].id<<" "<<stu[i].sum<<endl;
	}
  	return 0;
}

七、学生评定

描述

现有 N 名同学,每名同学有多个信息:学号、学业成绩、素质拓展成绩和综合分数(综合分数=7×学业成绩+3×素质拓展成绩)。综合分数达到学校优秀学生分数线的同学,会被判定为“优秀学生”,否则就不是优秀的学生。
请输出最终的评定结果。

输入描述

第一行一个整数 N。
接下来 N 行,每行 3 个整数,依次表示学号、学业成绩和素质拓展成绩。
最后一行是一个整数,表示学校的优秀学生分数线。

输出描述

N 行,每行一个学号和一个判断结果:如果该名学生是优秀的,输出 Excellent,否则输出 Not excellent

样例输入1

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

样例输出1

1223 Excellent
1224 Not excellent
1473 Not excellent
1556 Excellent

题解

#include <bits/stdc++.h>
using namespace std;
struct student{
	int id;
	int sum;
}stu[5005];
int you,n;
int main() {
	cin>>n;
	for(int i = 1;i<=n;i++){
		int order,xg,sg;
		cin>>order>>xg>>sg;
		stu[i].id = order;
		stu[i].sum = 7*xg+3*sg;
	}
	cin>>you;
	for(int i = 1;i<=n;i++){
		if(stu[i].sum>=you){
			cout<<stu[i].id<<" "<<"Excellent"<<endl;
		} 
		else{
			cout<<stu[i].id<<" "<<"Not excellent"<<endl;
		}
	}
  	return 0;
}

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值