[Jobdu] 1005:Graduate Admission

好久没有更新博客了,罪过罪过。。。

浙大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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值