一、题目描述
Input Specification:
Output Specification:
Sample Input:
11 6 3
2 1 2 2 2 3
100 100 0 1 2
60 60 2 3 5
100 90 0 3 4
90 100 1 2 0
90 90 5 1 3
80 90 1 0 2
80 80 0 1 2
80 80 0 1 2
80 70 1 3 2
70 80 1 2 3
100 100 0 2 4
Sample Output:
0 10
3
5 6 7
2 8
1 4
二、解题思路
一道大模拟题,按照题目要求进行排序,用一个二维数组(或一个vector数组)来存放每个学校的录取情况。最后遍历输出即可,实现细节见代码注释。
三、AC代码
#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 40010;
const int maxm = 101;
int quota[maxm];
vector<int> adm[maxm]; //录取的学生
int R[maxn];
struct Student
{
int Ge, Gi, id, rank; //高考分数,面试分数,id,排名
int apply[6]; //志愿学校
double Gf; //最终成绩
}stu[maxn];
bool cmp(Student a, Student b) //比较函数
{
if(a.Gf != b.Gf) return a.Gf > b.Gf;
else return a.Ge > b.Ge;
}
bool cmp2(int a, int b)
{
return a < b;
}
int main()
{
int N, M, K;
scanf("%d%d%d", &N, &M, &K);
for(int i=0; i<M; i++)
scanf("%d", "a[i]);
for(int i=0; i<N; i++)
{
stu[i].id = i;
scanf("%d%d", &stu[i].Ge, &stu[i].Gi);
stu[i].Gf = (stu[i].Ge + stu[i].Gi)/2.0; //计算最终成绩
for(int j=0; j<K; j++) scanf("%d", &stu[i].apply[j]);
}
sort(stu, stu+N, cmp);
for(int i=0; i<N; i++)
{
//更新排名
if(i == 0) stu[i].rank = 1;
else
{
if(stu[i].Ge == stu[i-1].Ge && stu[i].Gi == stu[i-1].Gi) stu[i].rank = stu[i-1].rank;
else stu[i].rank = i+1;
}
R[stu[i].id] = stu[i].rank;
for(int j=0; j<K; j++)
{
if(quota[stu[i].apply[j]] > 0) //如果志愿学校还有配额
{
adm[stu[i].apply[j]].push_back(stu[i].id);
quota[stu[i].apply[j]]--;
break;
}
else //无配额,检查当前同学的排名是否与这所学校上一个录取的同学排名相等
{
int sze = adm[stu[i].apply[j]].size();
if(stu[i].rank == R[adm[stu[i].apply[j]][sze-1]])
{
adm[stu[i].apply[j]].push_back(stu[i].id);
break;
}
}
}
}
for(int i=0; i<M; i++)
{
sort(adm[i].begin(), adm[i].end(), cmp2);
for(int j=0; j<adm[i].size(); j++)
{
if(j == 0) printf("%d", adm[i][j]);
else printf(" %d", adm[i][j]);
}
printf("\n");
}
return 0;
}