题解 P1068 【分数线划定】
这道题本质就是排序,分数高的优先,人数够了就划分数线,把同分的也算进来就行了。
其实这道题不要求你把全部数排序,堆排会快,桶排……
算一下,快排堆排n log n复杂度5000×5000 log2≤5000×13=65000
桶排是要看你怎么排了……
你可以强行开布尔数组存每一个序号与每一个成绩的对应,100×8999=899900这是慢一些的,但也可以过(冒泡都能过)
也可以用真正的计数排序,当当当!开一堆链表(或vector)存每一个成绩的序号,每个序号内部排序,其实也是很快的。
我图简单,用了模板库sort(快排)
我没有用结构体,用了一个编码存成绩与序号
由于先由大到小排成绩由小到大排序号
可以这样存:
有人成绩s,序号k,
则编码a=s×10000+10000-k
由于1000 ≤ k ≤ 9999 < 10000,其编码顺序肯定先由成绩决定
而由于序号是由小到大排序,与成绩相反,我就取其与10000的差,序号的从小到大就变为与成绩相同的从大到小了
编码的思想在很多题都有用
附代码
#include<cstdio>
#include<algorithm>
using namespace std;
int a[5001];
int main()
{
int n,m,i,s,k;
scanf("%d %d",&n,&m);
m+=m>>1;
for (i=0;i<n;i++)
scanf("%d %d",&k,&s),a[i]=s*10000+10000-k;
sort(a,a+n);
for (i=n-m-1;i>=0;i--)
if (a[n-m]/10000>a[i]/10000)
break;
printf("%d %d\n",a[n-m]/10000,n-i-1);
for (k=n-1;k>i;k--)
printf("%d %d\n",10000-a[k]%10000,a[k]/10000);
return 0;
}