题目描述
世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,A 市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的150%划定,即如果计划录取m名志愿者,则面试分数线为排名第(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。
现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。
输入描述:
第一行,两个整数,中间用一个空格隔开,其中n 表示报名参加笔试的选手总数,m表示计划录取的志愿者人数。输入数据保证向下取整后小于等于n。
第二行到第n+1行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号和该选手的笔试成绩。数据保证选手的报名号各不相同。
输出描述:
第一行,有两个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。
从第二行开始,每行包含两个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。
示例1
输入
6 3
9848 90
6731 88
1422 95
7483 84
8805 95
4162 88
输出
88 5
1422 95
8805 95
9848 90
4162 88
6731 88
说明
,向下取整后为 4。保证4个人进入面试的分数线为88,但因为88有重分,所以所有成绩大于等于 88 的选手都可以进入面试,故最终有 5 个人进入面试
解答
本题解法不唯一,这里将一种顺着思路来的。
重点算法:排序算法(排序很多,不同情况下用不同的方法,但是初学者不建议使用sort和qsort函数,这样你学不到排序的思想和精髓)。
先说一下思路。
首先,不清楚题意的自己再仔细读一遍。
好了,正式开始。首先要按报名者笔试的成绩从高到低排一波序。然后算出面试要求的分数线,达到才能进。最后挑出通过的人,数一数有几个人。
接下来是实现方法。
输入和排序没什么好讲的了。接下来是分数线,可以通过算希望录取的人来取得分数线。有了分数线就可以判断一下是否通过,通过了的就记录下来,最后一起输出。
在上代码之前先说一下注意事项。
1.数组清空(虽然这题没有影响,但还是有养成这个好习惯的必要)。
2.达到分数线的就可以进入面试环节,所以面试人数是大于等于预期人数的(因为分数刚好达到分数线的人可能有很多个)。
3.c++的不要用long long,c++不支持(切记切记!!!!)。
4.注意取值范围和变量类型(^ _ *)。
#include<iostream> using namespace std; int main() { int n,m,k[6000],s[6000],c,flag; //flag即为指向标,就是判断是否通过的标准 cin>>n>>m; for(int i=1;i<=n;i++) cin>>k[i]>>s[i];//报名号是整型,不是字符串 //接下来是重点——排序 for(int i=2;i<=n;i++)//排序只用执行n-1次就可以了,降序 for(int j=2;j<=n;j++) { if(s[j]>s[j-1]) { c=s[j];//c充当酱油瓶的角色 s[j]=s[j-1]; s[j-1]=c; c=k[j];//报名号也要跟着换 k[j]=k[j-1]; k[j-1]=c; } } for(int i=2;i<=n;i++) for(int j=2;j<=n;j++) { if(s[j]==s[j-1] && k[j]<k[j-1]) //再来一波循环,按报名号把同分的排一下,也可以直接和上一重合并 { c=k[j]; k[j]=k[j-1]; k[j-1]=c; } } m=m*1.5;//算要面试的人数,向下取整 flag=s[m];//取分数线 c=0; for(int i=1;i<=n;i++) { if(s[i]>=flag) c++;//因为分数等于s[m]的人可能有很多个 } cout<<flag<<" "<<c<<endl;//面试分数和人数 for(int i=1;i<=c;i++) { cout<<k[i]<<" "<<s[i]<<endl; } return 0; }
来源:木兮