题目描述
一年一度的小学信息学竞赛即将开始。为了选拔参加比赛的选手,某区进行了信息学选拔活动,因为名额有限,需要根据选拔考试的成绩由高到底选择参加市赛的人员。
选拔考试有3道试题,参加考试的学生人数有N个人,最终只能有M个人参加市赛。选拔规则如下:
先按总分从高到低排序,如果两个同学总分相同,再按第一题得分从高到低排序,如果两个同学总分和第一题得分都相同,那么规定考号小的同学排在前面,这样,每个学生的排序是唯一确定的。
你的任务是先根据输入的3道试题的分数(每道题总分100分)计算总分,然后按上述规则排序,最后按排名顺序输出能参加市赛的考号和总分。
输入
输入包含n+1行:
第1行为两个正整数N和M,表示参加选拔的学生人数和最终参加市赛的人数。
第2到N+1行,每行有3个用空格隔开的数字,每个数字都在O到100之间,第j行的3个数字依次表示考号为j-1的学生的第一、第二、第三道题目的成绩。每个学生的考号按照输入顺序编号为l~N (恰好是输入数据的行号减1)。
所给的数据都是正确的,不必检验。
输出
输出共有M行,每行是两个用空格隔开的正整数,依次表示前M名学生的考号和总分。
样例输入
5 2
78 44 40
91 91 83
98 51 54
61 88 33
77 46 83
样例输出
2 265
5 206
提示
0<=M<N<=300
解题思路:其实就是一道很简单的排序,先对总分进行降序排,如果总分相同按照第一道的成绩降序,如果总分和第一道都相同,就按照编号进行升序。看仔细题这道题目就是非常简单了。因为方便看采用了结构体。
附上代码。
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct Node{
int x; //第一道成绩
int y; //第二道成绩
int z; //第三道成绩
int s; //总分
int i; //编号
}a[350];
bool cmp(Node a,Node b){
if(a.s==b.s&&a.x==b.x ) return a.i < b.i ; //总分和第一道都相同
else if(a.s==b.s&&a.x != b.x) return a.x > b.x; //总分相同
else return a.s > b.s;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z );
a[i].s =a[i].x + a[i].y + a[i].z; //计算总分
a[i].i=i; //编号
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=m;i++)
printf("%d %d\n",a[i].i,a[i].s );
return 0;
}