洛谷 做题日记 P1068 分数线划分 难度 普及-

首先是题目
题目描述
世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,AA市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的150%150%划定,即如果计划录取mm名志愿者,则面试分数线为排名第m \times 150%m×150%(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。
现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。
输入格式
第一行,两个整数 n,m(5 ≤ n ≤ 5000,3 ≤ m ≤ n)中间用一个空格隔开,其中n表示报名参加笔试的选手总数,m表示计划录取的志愿者人数。输入数据保证m×150%向下取整后小于等于 n。
第二行到第 n+1 行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号 k(1000 ≤ k ≤ 9999)和该选手的笔试成绩 s(1 ≤ s ≤ 100)。数据保证选手的报名号各不相同。
输出格式
第一行,有2个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。
从第二行开始,每行包含2个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。

然后是代码

//看到这个题目我先想到结构体和数组两个方法,然后感觉数组更方便些,于是选择数组
#include
using namespace std;
int a[5000][2],m,n,l,k;
void swap(int &i,int &j)//交换函数,交换两个数的值,定义引用可以节省空间
{
	int k;
	k=i;
	i=j;
	j=k;
}
int main()
{
	int i,j;
	cin>>n>>m;
	m=m*3/2;//更新m的值 (刚才接收的已经用不到了)
	for(i=0;i<n;i++)
		cin>>a[i][0]>>a[i][1];//接收数据
	for(i=0;i<n;i++)//排序,按分数从大到小排序
	{
		for(j=i+1;j<n;j++)
		{
			if(a[i][1]<a[j][1])
			{
				swap(a[i][1],a[j][1]);//交换分数
				swap(a[i][0],a[j][0]);//交换编号
			}
			else if(a[i][1]==a[j][1])//如果分数一样,则编号小的在前
			{
				if(a[i][0]>a[j][0])
				{
					swap(a[i][0],a[j][0]);//因为分数一样,只需交换编号
				}
			}
		}
	}
	i=m-1;//重新定义i的值,从要录取的最后一个人开始
	do
	{
		if(a[i][1]==a[i+1][1])//如果最后一个人与后面一个人同分,则录取人数m+1,i向后移动一位。
		{
			m++;
			i++;
		}
		else//没有一样的就结束
			break;
	}while(1);
	cout<<a[m-1][1]<<" "<<m<<endl;//输出分数和人数
	for(i=0;i<m;i++)
		cout<<a[i][0]<<" "<<a[i][1]<<endl;
	return 0;
}

总结:写的时候因为一个小错误(把 j 写成 i )结果老是出错,编译也没发现,果然还是调试好啊 多试了几组数据 就搞定了。
本来认为排序的第一层可以减少循环次数(因为m以后若干个就不用排序了,结果已经出来了),但是仔细想了想和第m个分数一样的不确定,所以就只好这样了

你可能感兴趣的:(洛谷 做题日记 P1068 分数线划分 难度 普及-)