PAT A1080 Graduate Admission
根据分数进行排名,再根据志愿学校依次录取,如果有与学校录取的最后一名排名相同且志愿相同的学生,都要一并录取,保证公平,即使已经没有名额(还好没说保护一志愿) 那么顺着题意将输入放入学生数组,另搞了一个rank数组保存学生ID,之后根据学生分数排序rank数组(多弄了一个rank是因为写到录取的时候,判断如果没有名额了,就去看看被录取的最后一名跟我是不是一个水平,如果是的话,他能上那我也能上。而录取数组里存的是学生的原始ID,如果这时候学生数组被排序了,则不能根据原始ID直接定位) rank排好之后一个个拿出来去申请录取,注意如果申请成功则需break,否则就可能脚踏几条船咯
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct School{
int quota;
vector< int > admit;
} ;
vector< School> vs;
struct Student{
int idx;
int GE, GI, GF;
vector< int > prefer;
int rank;
} ;
vector< Student> vst;
vector< int > rank_;
bool cmp ( int s1, int s2) {
return vst[ s1] . GF != vst[ s2] . GF ? vst[ s1] . GF > vst[ s2] . GF : vst[ s1] . GE > vst[ s2] . GE;
}
bool applicate ( int stid, int sid) {
if ( vs[ sid] . quota > 0 ) {
vs[ sid] . admit. push_back ( stid) ;
vs[ sid] . quota -- ;
return true ;
} else {
int id = vs[ sid] . admit[ vs[ sid] . admit. size ( ) - 1 ] ;
if ( vst[ id] . GF == vst[ stid] . GF && vst[ id] . GE == vst[ stid] . GE) {
vs[ sid] . admit. push_back ( stid) ;
return true ;
}
}
return false ;
}
int main ( ) {
int N, M, K;
cin >> N >> M >> K;
vs. resize ( M) ;
vst. resize ( N) ;
rank_. resize ( N) ;
for ( int i = 0 ; i < M; i ++ ) cin >> vs[ i] . quota;
for ( int i = 0 ; i < N; i ++ ) {
vst[ i] . idx = i;
rank_[ i] = i;
cin >> vst[ i] . GE >> vst[ i] . GI;
vst[ i] . GF = vst[ i] . GE + vst[ i] . GI;
for ( int j = 0 ; j < K; j ++ ) {
int tmp;
cin >> tmp;
vst[ i] . prefer. push_back ( tmp) ;
}
}
sort ( rank_. begin ( ) , rank_. end ( ) , cmp) ;
for ( int i = 0 ; i < rank_. size ( ) ; i ++ ) {
int stid = rank_[ i] ;
for ( int j = 0 ; j < vst[ stid] . prefer. size ( ) ; j ++ )
if ( applicate ( stid, vst[ stid] . prefer[ j] ) ) break ;
}
for ( int i = 0 ; i < M; i ++ ) {
sort ( vs[ i] . admit. begin ( ) , vs[ i] . admit. end ( ) ) ;
for ( int j = 0 ; j < vs[ i] . admit. size ( ) ; j ++ ) {
cout << vs[ i] . admit[ j] ;
if ( j < vs[ i] . admit. size ( ) - 1 ) cout << ' ' ;
}
cout << endl;
}
return 0 ;
}