好久没有更新博客了,罪过罪过。。。
浙大2011机试最后一题,题目久度OJ上有。
话说网上大牛都认为此题很水,结果我做了long long time,看来不是题目水,是我太水了,囧。。。
其实题目就是条件多了一些,没有什么复杂的算法,主要卡在条件的处理上。最初的想法分成了三种情况(数组先排序是肯定的了)
1.申请人的final分数和下一个申请人的final分数不等
2.申请人的final分数和下一个申请人的final分数相等,但是入学考试分数不等
3.final分数相等,入学分数也相等
对这三种情况依次处理,根据每个人的choice找到对应的学校。。。
其实,如果从学校的角度看就简单的多了(参考这篇文章)
1.申请人选择的学校尚有空余位置
2.申请的学校录取人数已满,但是和最后一个录取的人有相同的rank
一个小trick就是对申请者按照final分数和入学分数进行快排,而且还是降序。
最后输出也花了不少时间,因为快排不稳定,所以最后输出时还得进行一次排序。
下面是我写的很挫的代码。。。
#include <stdio.h>
#include <stdlib.h>
#define N 40000
#define K 5
typedef struct {
int id;
int ge;
int gi;
int final;
int choice[K];
}applicant;
typedef struct {
int sum;
int limit;
int p[N];
}school;
int cmp(const void *p, const void *q) {
applicant *a = (applicant *)p;
applicant *b = (applicant *)q;
if(a->final != b->final) return b->final - a->final;
else return b->ge - a->ge;
}
int cmp2(const void *p, const void *q) {
return *(int *)p - *(int *)q;
}
int main() {
int n, k, m;
int i, j;
applicant *app;
school *sch;
int t;
while(scanf("%d %d %d", &n, &m, &k) != EOF) {
sch = (school *)malloc(m * sizeof(school));
for(i = 0; i < m; i++) {
scanf("%d", &sch[i].limit);
sch[i].sum = 0;
}
app = (applicant *)malloc(n * sizeof(applicant));
for(i = 0; i < n; i++) {
scanf("%d %d", &app[i].ge, &app[i].gi);
app[i].id = i;
app[i].final = (app[i].ge + app[i].gi) / 2;
for(j = 0; j < k; j++)
scanf("%d", &app[i].choice[j]);
}
qsort(app, n, sizeof(applicant), cmp);
for(i = 0; i < n; i++) {
for(j = 0; j < k; j++) {
t = app[i].choice[j];
if(sch[t].sum < sch[t].limit) {
sch[t].p[sch[t].sum++] = i;
break;
}
else if(app[sch[t].p[sch[t].sum-1]].final == app[i].final &&
app[sch[t].p[sch[t].sum-1]].ge == app[i].ge) {
sch[t].p[sch[t].sum++] = i;
break;
}
}
}
for(i = 0; i < m; i++) {
for(j = 0; j < sch[i].sum; j++) sch[i].p[j] = app[sch[i].p[j]].id;
qsort(sch[i].p, sch[i].sum, sizeof(int), cmp2);
for(j = 0; j < sch[i].sum - 1; j++) {
printf("%d ", sch[i].p[j]);
}
if(j < sch[i].sum)
printf("%d\n", sch[i].p[j]);
else
puts("");
}
free(sch);
free(app);
}
return 0;
}