A1080 Graduate Admission (30point(s))
题意
给出学生的成绩,k个志愿,k个学校的录取名额,学生按照总体成绩和Ge排名,排名靠前的优先录取,如果那所学校已经满了但是录取的最后一位学生的排名和他相同,也可以录取。
最后输出各个学校录取的学生的id。(从0到n-1)
如果该学生没有被任何学校录取,那么非常遗憾,他就名落孙山了,这也是非常令人扼腕叹息的事情。唉。
思路
注意一旦录取成功后break。
总结
排序题。结构体School虽然显得有点多余,但是还是比较符合直觉的。
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
#include"bits/stdc++.h"
using namespace std;
struct Student {
int g1,g2;
double g;
int rank;
int id;
vector<int> a;
};
struct School {
int cnt;
vector<Student*> stus;
};
int main() {
//freopen("input.txt","r",stdin);
int n,m,k;
cin >> n >> m >> k;
map<int,School> id2School;
for(int i=0; i<m; i++) {
int t;
scanf("%d",&t);
id2School[i].cnt = t;
}
vector<Student> stus(n);
for(int i=0; i<n; i++) {
stus[i].a.resize(k);
stus[i].id = i;
scanf("%d%d",&stus[i].g1,&stus[i].g2);
stus[i].g = (stus[i].g1 + stus[i].g2)/2.0;
for(int j=0; j<k; j++) scanf("%d",&stus[i].a[j]);
}
sort(stus.begin(),stus.end(),[](Student& s1,Student& s2) {
if(s1.g == s2.g)
return s1.g1 > s2.g1;
return s1.g > s2.g;
});
// give rank
for(int i=0; i<n; i++) {
if(i == 0) {
stus[i].rank = i;
continue;
} else if(stus[i].g == stus[i-1].g && stus[i].g1 == stus[i-1].g1) {
stus[i].rank = stus[i-1].rank;
} else
stus[i].rank = i;
}
// admission
for(auto& stu:stus) {
for(int t:stu.a) {
School& school = id2School[t];
if(school.cnt) {
school.cnt --;
school.stus.push_back(&stu);
break;
} else if(stu.rank == school.stus.back()->rank) {
school.stus.push_back(&stu);
break;
}
}
}
// output
for(int i=0; i<m; i++) {
School& school = id2School[i];
sort(school.stus.begin(),school.stus.end(),[](Student* s1,Student* s2) {
return s1->id < s2->id;
});
for(int j=0; j<school.stus.size(); j++) {
printf("%d",school.stus[j]->id);
if(j != school.stus.size()-1) printf(" ");
}
cout << endl;
}
}