A1080 Graduate Admission [排序]
题目大意:录取学生类似模拟高考填写志愿
具体思路:
- 定义两个结构体,一个存学生信息,一个存学校信息,输入完后排序,再循环扫描学生的信息,如果满足条件就存入学校的信息。
- 最后循环扫描学校信息,输出录入的学生信息,注意这里还有一个排序,要按照id从小到大输出
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct student
{
int ge, gi, sum;
int rank, id;
int cho[6];
}stu[40001];
struct school
{
int quota, stunum;
int id[40010];
int lastid;
}sch[101];
bool cmp1(student a, student b)
{
if (a.sum != b.sum)
return a.sum > b.sum;
else
return a.ge > b.ge;
}
bool cmp2(int a,int b)
{
return stu[a].id < stu[b].id;
}
int main()
{
int n, k, m; //人数,招生学校数量,可填志愿数
cin >> n >> k >> m;
for (int i = 0; i < k; i++)
{
cin >> sch[i].quota;
sch[i].stunum = 0;
sch[i].lastid = -1;
}
for (int i = 0; i < n; i++)
{
stu[i].id = i;
cin >> stu[i].ge >> stu[i].gi;
stu[i].sum = stu[i].ge + stu[i].gi;
for (int j = 0; j < m; j++) {
cin >> stu[i].cho[j];
}
}
sort(stu, stu + n, cmp1);
stu[0].rank = 1;
for (int i = 1; i < n; i++) {
if (stu[i].sum == stu[i - 1].sum&&stu[i].ge==stu[i-1].ge)
{
stu[i].rank = stu[i - 1].rank;
}
else
{
stu[i].rank = i + 1;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j <m; j++)
{
int choice = stu[i].cho[j];
int num = sch[choice].stunum;
int last = sch[choice].lastid;
if (num < sch[choice].quota || (last != -1 && stu[i].rank == stu[last].rank))
{
sch[choice].id[num] = i;
sch[choice].lastid = i;
sch[choice].stunum++;
break; //录取了不用再考虑了
}
}
}
for (int i = 0; i < k; i++)
{
if (sch[i].stunum > 0)
{
sort(sch[i].id, sch[i].id + sch[i].stunum, cmp2);
for (int j = 0; j < sch[i].stunum; j++)
{
cout << stu[sch[i].id[j]].id;
if (j < sch[i].stunum - 1)
{
cout << " ";
}
}
}
cout << endl;
}
}