PAT-A1080-Graduate Admission-附题解

PS:刷题时的代码,基本没有改过,测试点都通过了。放上来总结一下思路与方法。

1.题目阐述

要求:

  1. ranked according to their final grades,and their national entrance exam grade GE second
  2. if the quota of one’s most preferred shcool is not exceeded, one by one in order.
  3. rejected by all of preferred schools, then this unfortunate applicant will be rejected.
  4. applications the same rank, to the same school,then that school must admit all the applicants with the same rank,even if its quota will be exceeded.

2.题目思路

这里每次外循环得到一个录取方向时就需要检查有无同成绩同志向的申请,如果有就需要同时加入该学校直至不满足需求。下标i的变换根据题意来写的,因此最好读懂题目再看我的代码…

可以看到逻辑比较复杂,我竟然只debug了3次…

阅读理解题。没有用到高深的算法知识,就是考验编程者的基本工,稍微超了时,可能是我没掌握到精髓把…

g_shchools–数组,记录招录数
applicants–结构数组 sort 排序分数
vector-记录招生简历编号

3.题解代码

我的代码如下:

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;


int g_school[101];
vector<int> mark_lst[101];
struct node{
	int id;
	int f_grade;
	int Ge;
	int rank;
	vector<int> will;
}Node[40001];


bool cmp(node n1, node n2){
	if (n1.f_grade != n2.f_grade) return n1.f_grade > n2.f_grade;
	return n1.Ge > n2.Ge;
}

int N, M, K;

int main(){


	scanf("%d %d %d", &N, &M, &K);

	int Ge, Gi;
	for (int i = 0; i < M; i++){
		scanf("%d", &g_school[i]);
	}

	for (int i = 0; i < N; i++){
		scanf("%d %d", &Ge, &Gi);
		Node[i].f_grade = (Ge + Gi) / 2;
		Node[i].Ge = Ge;
		Node[i].id = i;
		int temp;
		for (int j = 0; j < K; j++){
			scanf("%d", &temp);
			Node[i].will.push_back(temp);
		}
	}


	//排序
	sort(Node, Node + N, cmp);
	node temp;
	int g_id;
	for (int i = 0; i < N; i++){
		temp = Node[i];
		for (int j = 0; j < temp.will.size(); j++){
			g_id = temp.will[j];
			if (g_school[g_id] > 0){
 
				mark_lst[g_id].push_back(Node[i].id);
				g_school[g_id] -= 1;

				//寻找下文水平一致且同志向的选手
				int k = i + 1;
				while (i < N - 1 && Node[i].f_grade == Node[k].f_grade&&Node[i].Ge == Node[k].Ge){
					bool flag = true;

					for (vector<int>::iterator it = Node[k].will.begin(); it != Node[k].will.end(); it++){
						int temp_g_id = *it;
						if (temp_g_id != g_id && g_school[temp_g_id] != 0){
							flag = false;
							break;
						}
						else if (temp_g_id == g_id){

							mark_lst[g_id].push_back(Node[k].id);
							g_school[g_id] -= 1;
							i = k;
							break;
						}
					}

					if (flag == false){
						break;
					}
					else{
						k += 1;
					}
				}
				break;//找到了就是退出的
			}

		}
	}


	//输出

	for (int i = 0; i < M; i++){
		if (mark_lst[i].size() != 0){
            sort(mark_lst[i].begin(),mark_lst[i].end());
			for (int j = 0; j < mark_lst[i].size(); j++){
				if (j == mark_lst[i].size() - 1) printf("%d\n", mark_lst[i][j]);
				else printf("%d ", mark_lst[i][j]);
			}
		}
		else{
			printf("\n");
		}
	}
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值