[PAT解题报告] Graduate Admission
其实这个题也不难,算作模拟题吧。给定若干个学校,若干个学生。每个学校有一定的招生名额,每个学生可以报一些志愿,志愿分先后,表示他想去的学校。规则:
(1)
每个学生有两个成绩,根据平均分,和一门成绩对学生进行排序——平均分越高则学生越好,平均分相同,第一门课越高则越好,否则学生排名相同。这里需要说一句,其实按平均分排和按总分排是一样的,不用真的除以2。
(2)
每个学校有一定名额,按照学生志愿,优先录取好的学生,但是如果学校录取了某个学生,还有一个和他一样好的学生也报了这个学校,则学校也应该录取他,即使录取他会使人数已经超过了学校的名额。
(3) 学生按照志愿选取学校。
做法: 先对学生排序,好的学生优先。一次看每个学生的每个志愿,看看学校能不能录取。录取原则是关键:
(a) 如果学校没录取满,显然要这个学生——因为他是目前最好的了,更好的已经都录取完了
(b) 如果学校录取的人数已经超额,则要看最后一个录取的学生(最差的)和现在这个是不是一样好,如果一样好,则必须要。
按照这个规则模拟就好了。输出学校录取的学生的时候,别忘记按照id再排序一次。
代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
pair<int,int> student[40004];
int want[40004][5];
vector<int> school[102];
int id[40004];
int c[102];
bool cmp(const int &a,const int &b) {
return student[a] > student[b];
}
int main() {
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for (int i = 0; i < m; ++i) {
scanf("%d",c + i);
}
for (int i = 0; i < n; ++i) {
scanf("%d%d",&student[i].second,&student[i].first);
id[i] = i;
student[i].first += student[i].second;
for (int j = 0; j < k; ++j) {
scanf("%d",&want[i][j]);
}
}
sort(id, id + n, cmp);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < k; ++j) {
if ((c[want[id[i]][j]] > school[want[id[i]][j]].size()) || (student[school[want[id[i]][j]].back()] == student[id[i]])) {
school[want[id[i]][j]].push_back(id[i]);
break;
}
}
}
for (int i = 0; i < m; ++i) {
sort(school[i].begin(),school[i].end());
for (int j = 0; j < school[i].size(); ++j) {
if (j) {
putchar(' ');
}
printf("%d",school[i][j]);
}
puts("");
}
return 0;
}
原题链接: http://www.patest.cn/contests/pat-a-practise/1080

