一、长方形比大小
描述
长方形家族有个很俗气的传统:谁大谁优先。 “比大小”的规则是:
1.面积大的优先
2.面积相同时,周长长的优先
请将n个长方形按“比大小”的规则排序后,输出每个长方形的序号。长方形的序号是1~n,和长方形的输入顺序一致。
输入描述
第1行,输入一个小于100的正整数,表示长方形的个数;
接下来的100行,每行输入一个长方形的长和宽(都是正整数),中间用单个空格隔开。
输出描述
输出n个正方形的序号。每个长方形占一行。
样例输入1
5
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个选手按如下规则排序后,输出运动员的序号。
- 成绩好的选手排前面;
- 成绩相同的选手,序号小的选手排前面。
输入描述
输入共有 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;
}