题解 | 分数线划定-NOIP2009普及组复赛A题
分数线划定
https://ac.nowcoder.com/acm/contest/237/A
题目描述
世博会志愿者的选拔工作正在 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;
} 来源:木兮


海康威视公司福利 1121人发布