Each applicant will have to provide two grades: the national entrance exam grade GE , and the interview grade GI . The final grade of an applicant is (GE + GI ) / 2. The admission rules are:
Each input file contains one test case. Each case starts with a line containing three positive integers: N (<=40,000), the total number of applicants; M (<=100), the total number of graduate schools; and K (<=5), the number of choices an applicant may have.
In the next line, separated by a space, there are M positive integers. The i-th integer is the quota of the i-th graduate school respectively.
Then N lines follow, each contains 2+K integers separated by a space. The first 2 integers are the applicant's GE and GI, respectively. The next K integers represent the preferred schools. For the sake of simplicity, we assume that the schools are numbered from 0 to M-1, and the applicants are numbered from 0 to N-1.
For each test case you should output the admission results for all the graduate schools. The results of each school must occupy a line, which contains the applicants' numbers that school admits. The numbers must be in increasing order and be separated by a space. There must be no extra space at the end of each line. If no applicant is admitted by a school, you must output an empty line correspondingly.
11 6 3 2 1 2 2 2 3 100 100 0 1 2 60 60 2 3 5 100 90 0 3 4 90 100 1 2 0 90 90 5 1 3 80 90 1 0 2 80 80 0 1 2 80 80 0 1 2 80 70 1 3 2 70 80 1 2 3 100 100 0 2 4
0 10 3 5 6 7 2 8 1 4
var kList = E.Range(0, k); var studentList = ( from i in E.Range(0, n) let GE = nextInt() let GT = GE + nextInt() let APP = ( from j in kList select nextInt() ).ToArray() orderby GT descending, GE descending select new { id = i, gt = GT, ge = GE, app = APP }) .ToArray();
using System; using System.Text; using System.Collections.Generic; using E = System.Linq.Enumerable; using System.Linq; class Program { string[] tokens; int lastToken; int nextInt() { if (lastToken >= tokens.Length) { string tmp = Console.ReadLine(); tokens = tmp.Split(new char[] { ' ' }); lastToken = 0; } return int.Parse(tokens[lastToken++]); } Program() { tokens = new string[1]; lastToken = 1; int n = nextInt(), m = nextInt(), k = nextInt(); int[] maxAcc = new int[m]; for (int i = 0; i < m; i++) maxAcc[i] = nextInt(); List<int>[] schoolAccept = new List<int>[m]; for (int i = 0; i < m; i++) schoolAccept[i] = new List<int>(); int[] ge = new int[n]; int[] gi = new int[n]; int[][] appli = new int[n][]; for (int i = 0; i < n; i++) { ge[i] = nextInt(); gi[i] = nextInt(); appli[i] = new int[k]; for (int j = 0; j < k; j++) appli[i][j] = nextInt(); } var studentList = ( from i in E.Range(0, n) let GE = ge[i] let GT = ge[i] + gi[i] let APP = appli[i] orderby GT descending, GE descending select new { id = i, gt = GT, ge = GE, app = APP }) .ToList(); int[] rank = new int[n]; for (int i = 0; i < n; i++) { var item = studentList[i]; var lastItem = studentList[i - 1<0?0:i-1]; if (i!=0 && lastItem.gt == item.gt && lastItem.ge == item.ge) rank[item.id] = rank[lastItem.id]; else rank[item.id] = i; for (int j = 0; j < k; j++) { int sel = item.app[j]; if (schoolAccept[sel].Count < maxAcc[sel] || rank[schoolAccept[sel].Last()] == rank[item.id]) { schoolAccept[sel].Add(item.id); break; } } } for (int i = 0; i < m; i++) { schoolAccept[i].Sort(); for (int j = 0; j < schoolAccept[i].Count; j++) { Console.Write((j == 0 ? "" : " ") + schoolAccept[i][j]); } Console.WriteLine(""); } } public static void Main(String[] args) { new Program(); } }
/* 题意:n个学生可以填k个志愿,m个学校有quota个招生名额,学生优先考虑第一志愿, 不录取则顺延后面志愿,学校按照ge+gi成绩排名,如果相同,则按ge排名, 如果一个学校录取了x同学,并且有y同学和x同学两个成绩相同,则即是名额不够也都要录取, 求最后的录取名单 思路:将学生成绩降序排序,访问完每个人的k个志愿(**分高的先挑学校**)再继续下个人, 如果第j志愿有名额,直接录取; 如果第j志愿没有名额了就看看这个学校(第j志愿)有没有招收两项成绩都跟自己相同的, 有自己就被录取。 */ #include <bits/stdc++.h> using namespace std; const int AX = 4e4 + 6 ; int n , m , k ; int quota[105] ; struct Node { int ge , sum ; int id ; int zy[6] ; bool operator < ( const Node &a )const { if( sum == a.sum ) return ge > a.ge ; return sum > a.sum ; } } st_g[AX] ; map<int,int>ID; vector<Node>st ; vector<int>res[105] ; int main() { scanf("%d%d%d",&n,&m,&k); for( int i = 0 ; i < m ; i++ ) { scanf("%d","a[i]); } int x ; for( int i = 0 ; i < n ; i++ ) { scanf("%d%d",&st_g[i].ge,&x); st_g[i].id = i ; st_g[i].sum = x + st_g[i].ge ; for( int j = 0 ; j < k ; j++ ) { scanf("%d",&x); st_g[i].zy[j] = x ; } st.push_back(st_g[i]); } sort( st.begin() , st.end() ); for( int i = 0 ; i < n ; i++ ) { ID[st[i].id] = i ; } for( int i = 0 ; i < n ; i++ ) { for( int j = 0 ; j < k ; j++ ) { int zy = st[i].zy[j] ; if( quota[zy] > 0 ) { quota[zy] -- ; res[zy].push_back(st[i].id); break ; } else { int kk = res[zy].size() - 1 ; if( st[ID[res[zy][kk]]].sum == st[i].sum && st[i].ge == st[ID[res[zy][kk]]].ge ) { quota[zy] -- ; res[zy].push_back(st[i].id) ; break ; } } } } for( int i = 0 ; i < m ; i++ ) { sort( res[i].begin() , res[i].end() ); if( !res[i].size() ) printf("\n"); else { int len = res[i].size() ; for( int j = 0 ; j < len ; j++ ) { printf("%d",res[i][j]); if( j != len - 1 ) printf(" "); } if( i != m - 1 ) printf("\n"); } } return 0 ; }
#include <iostream> #include <vector> #include <algorithm> using namespace std; struct info { unsigned short id; //(备注:)采用unsigned short 是因为满足大于40000的要求 unsigned short Ge; //如果采用int, info arr[40000] 会造成内存溢出 float Gsum; }; bool cmp(info a, info b) { if (a.Gsum == b.Gsum) return a.Ge > b.Ge; else return a.Gsum > b.Gsum; } int main() { int N, M, K, Ge, Gi, vol; cin>>N>>M>>K; info arr[40000]; //学生集合; vector<int> voluntary[40000]; //学生志愿 vector<int> admitSchool[100]; //大学集合-招到学生的编号 int numOfStu[101]; //大学招生人数 int curNum[101] = {0}; //当前大学招生的人数 for (int i=0; i<M; i++) { cin>>numOfStu[i]; } for (int i=0; i<N; i++) { cin>>Ge>>Gi; arr[i].id = i; arr[i].Ge = Ge; arr[i].Gsum = float(Ge+Gi)/2.0; for (int j=0; j<K; j++) { cin>>vol; voluntary[i].push_back(vol); } } sort(arr, arr+N, cmp); //完成学生的排名,从高到低 for (int i=0; i<N; i++) { for (int j=0; j<K; j++) { int choose = voluntary[arr[i].id][j]; //当前志愿 if (numOfStu[choose] > curNum[choose]) //人未招满,直接进入vector { admitSchool[choose].push_back(arr[i].id); curNum[choose]++; break; } else //招满情况,比较报考学校最后一名学生的成绩和当前学生的成绩 { int lastId = admitSchool[choose].back(), callID; for (int k=0; k<i; k++) { if (arr[k].id == lastId) { callID = k; break; } } if (arr[callID].Ge==arr[i].Ge && arr[callID].Gsum==arr[i].Gsum) { admitSchool[choose].push_back(arr[i].id); curNum[choose]++; break; } } } } for (int i=0; i<M; i++) { sort(admitSchool[i].begin(), admitSchool[i].end()); bool flag = false; for (int j=0; j<curNum[i]; j++) { if (!flag) { cout<<admitSchool[i][j]; flag = true; } else cout<<" "<<admitSchool[i][j]; } cout<<endl; } return 0; }
#include <iostream> #include <vector> #include <set> using namespace std; #define MAX 40009 int N, M, K, quota[109]; int E[MAX], I[MAX], goal[MAX][10]; set<int> res[109];int lastStu[109]; typedef struct Stu { int id; Stu() :id(-1) {} Stu(int x) :id(x) {} bool operator <(Stu s)const {//<表示比学生s排名绝对地更靠前 if (E[id] + I[id] > E[s.id] + I[s.id])return true; else if (E[id] + I[id] == E[s.id] + I[s.id]) { if (E[id] > E[s.id])return true; else return false; } else return false; } }Stu; multiset<Stu> gList; int main() { cin >> N >> M >> K; set<int> emp_set; for (int i = 0; i < M; ++i) { cin >> quota[i]; res[i] = emp_set; } for (int i = 0; i < N; ++i) { cin >> E[i] >> I[i]; for (int j = 0; j < K; ++j)cin >> goal[i][j]; gList.insert(Stu(i)); } int ID, school; for (auto it = gList.begin(); it != gList.end();++it) { ID = it->id; for (int j = 0; j < K; ++j) { school = goal[ID][j]; if (E[ID] + I[ID] == E[lastStu[school]] + I[lastStu[school]] && E[ID] == E[lastStu[school]] || res[school].size() < quota[school]) { res[school].insert(ID); lastStu[school] = ID; break; } } } for (int i = 0; i < M; ++i) { for (auto it = res[i].begin(); it != res[i].end(); ) { cout << *it; if (++it != res[i].end())cout << " "; } if (i < M - 1)cout << endl; } return 0; }
#include <bits/stdc++.h> using namespace std; const int maxn = 4e4 + 5; const int maxm = 100 + 5; int n, m, k, most[maxm], laste[maxm], lasta[maxm]; struct node{ int ge, gi, id; int a[10]; bool operator <( const node &x )const{ //排序规则,总分高在前,若总分相等则Ge高的在前 if( ge+gi==x.ge+x.gi ) return ge>x.ge; //不用除以2,也不用开double return ge+gi>x.ge+x.gi; } } stu[maxn]; vector<int> clg[maxm]; bool vis[maxn]; int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); cin >> n >> m >> k; for( int i=0; i<m; i++ ) cin >> most[i]; for( int i=0; i<n; i++ ){ cin >> stu[i].ge >> stu[i].gi; stu[i].id = i; for( int j=0; j<k; j++ ) cin >> stu[i].a[j]; } sort( stu, stu+n ); //分高的先选,把所有志愿遍历一遍 for( int j=0; j<n; j++ ){ for( int i=0; i<k; i++ ){ if( vis[stu[j].id] ) continue; //如果已经被录取则ontinue int cid = stu[j].a[i]; if( clg[cid].size()<most[cid] ){ //编号cid的大学没招满,直接录取 clg[cid].push_back(stu[j].id); lasta[cid] = (laste[cid]=stu[j].ge)+stu[j].gi; vis[stu[j].id]=1; }else if( lasta[cid]==stu[j].ge+stu[j].gi && laste[cid]==stu[j].ge ){ //如果当前学生和编号为cid大学的最后一名分相同则录取 clg[cid].push_back(stu[j].id); vis[stu[j].id] = 1; } } } for( int i=0; i<m; i++ ){ sort(clg[i].begin(), clg[i].end()); //字典序输出 int siz = clg[i].size(); if( !siz ) cout << endl; else for( int j=0; j<siz; j++ ){ if( j ) cout << " "; cout << clg[i][j]; } cout << endl; } return 0; }
#include <stdio.h> #include <iostream> #include <vector> #include <set> #include <algorithm> using namespace std; const int maxn = 40001; const int maxm = 101; struct Applicant { int Ge, Gi, Rank, id; float final_score; vector<int> choice; }; int quota[maxm]; Applicant applicants[maxn]; bool cmp(Applicant a, Applicant b) { if(a.final_score != b.final_score) { return a.final_score > b.final_score; } else { return a.Ge > b.Ge; } } set<int> ans[maxm]; int main() { int n, m, k; scanf("%d %d %d", &n,&m, &k); for(int i=0; i<m; i++) { scanf("%d", quota+i); } for(int i=0; i<n; i++) { scanf("%d %d", &applicants[i].Ge, &applicants[i].Gi); for(int j=0; j<k; j++) { int tmp; scanf("%d", &tmp); applicants[i].choice.push_back(tmp); } applicants[i].final_score = (float)(applicants[i].Ge + applicants[i].Gi)/2; applicants[i].id = i; } sort(applicants, applicants+n, cmp); applicants[0].Rank = 0; for(int i=1; i<n; i++) { if(applicants[i].final_score == applicants[i-1].final_score && applicants[i].Ge == applicants[i-1].Ge) { applicants[i].Rank = applicants[i-1].Rank; } else { applicants[i].Rank = i; } } int prev_rank[maxm]; fill(prev_rank, prev_rank+maxm, -1); for(int i=0; i<n; i++) { for(int j=0; j<k; j++) { int school_index = applicants[i].choice[j]; if(quota[school_index] > 0 || applicants[i].Rank == prev_rank[school_index]) { quota[school_index]--; ans[school_index].insert(applicants[i].id); prev_rank[school_index] = applicants[i].Rank; break; } } } for(int i=0; i<m; i++) { if(!ans[i].empty()) { set<int>::iterator it = ans[i].begin(); printf("%d", *it); it++; for(; it!=ans[i].end(); it++) { printf(" %d", *it); } } printf("\n"); } }
#include<bits/stdc++.h> using namespace std; const int N = 4e4 + 10; struct Stu { int x, y, id, b[10]; void input(int k, int idx) { scanf("%d%d", &x, &y); id = idx; for (int i = 0;i < k;i++) scanf("%d", &b[i]); } bool operator < (const Stu &o) const { if (x + y != o.x + o.y) return x + y > o.x + o.y; return x > o.x; } bool operator == (const Stu &o) const { return x == o.x && y == o.y; } } stu[N], stu2[N]; int n, m, k, a[N]; vector<int> vec[N][10], tmp; int main() { //freopen("in.txt", "r", stdin); scanf("%d%d%d", &n, &m, &k); for (int i = 0;i < m;i++) { scanf("%d", &a[i]); } for (int i = 0;i < n;i++) { stu[i].input(k, i); stu2[i] = stu[i]; } sort(stu, stu + n); for (int i = 0;i < n;i++) { int idx = stu[i].id; for (int j = 0;j < k;j++) { int sc = stu[i].b[j]; if (a[sc] > 0) { a[sc]--, vec[sc][j].push_back(idx); break; } else if (vec[sc][j].size() && stu2[vec[sc][j].back()] == stu[i]) { vec[sc][j].push_back(idx); break; } } } for (int i = 0;i < m;i++) { tmp.resize(0); for (int j = 0;j < k;j++) { for (int x : vec[i][j]) tmp.push_back(x); } sort(tmp.begin(), tmp.end()); for (int j = 0;j < tmp.size();j++) { printf("%d", tmp[j]); if (j != tmp.size() - 1) printf(" "); } printf("\n"); } return 0; }为什么我最后一个点错了,有没有大佬帮忙看看那里出了问题
更多PAT题解--acking=you.github.io
实际上就和我们高考录取的过程是一样的。
题目是给出了N个考生的两种成绩(初试和复试)。
每个考生填满K个学校志愿。
然后通过成绩的高低(初试和复试的总和)决定录取的先后顺序。
每个学校有相应的名额限制,如果出现两个初试和复试分数都完全一样的人,则名额不存在限制。
最后要我们输出每个学校的录取名单(以0~N-1代号表示学生)。
AdmissionList[i]
数组存下编号为 i 的学校的录取情况) AdmissionList[i]
数组存下录取情况的过程中,需要判断这个学校是否已经录满了,如果录取满了,则和它的最低分进行比较,如果和它完全相同则继续录取(不可能比它大,因为本就已经排好序进行录取的) AdmissionList
打印结果即可。 基本变量
int *schoolN; //存储每个学校的限额 int **studentN; //存储每个学生的分数和志愿 vector<tuple<int, int, int>> students_sort; //这个只是用来排序的工具 vector<tuple<int, int, int>> *AdmissionList;//存储每个学校的录取名单 /*其实可以把tuple用自定义的数据结构代替,只是C++11标准自带我就直接拿这个过来用了*/
tuple的使用方法
make_tuple() //可以用于创建tuple对象 get<0~N>(tuple<>) //0~N表示要访问的下标
void Input() {//先把数据存起来再说 ios::sync_with_stdio(false); cin >> N >> M >> K; schoolN = new int[M]; studentN = new int *[N]; students_sort.resize(N); AdmissionList = new vector<tuple<int, int, int>>[M]; for (int i = 0; i < M; i++) { int x; cin >> x; schoolN[i] = x; } for (int i = 0; i < N; i++) { int n = 2 + K; int *t = new int[n]; for (int j = 0; j < n; j++) { int x; cin >> x; t[j] = x; } studentN[i] = t; } }
对学生通过分数进行排序,决定志愿录取的先后顺序
bool cmp1(tuple<int, int, int> &a, tuple<int, int, int> &b) {//如果总成绩不相同,则成绩高的放前面,否则再看初试成绩 return (get<0>(a) > get<0>(b)) || (get<0>(a) == get<0>(b) && get<1>(a) > get<1>(b)); }
用于对答案编号按照从小到大输出
bool cmp2(tuple<int, int, int> &a, tuple<int, int, int> &b) { return get<2>(a) < get<2>(b); }
用于判断两个学生是否完全相同和得到学生编号
inline bool IsEqual(tuple<int, int, int> &a, tuple<int, int, int> &b) { return get<0>(a) == get<0>(b) && get<1>(a) == get<1>(b); } inline int get_val(tuple<int, int, int> &a) { return get<2>(a); }
void solve() { for (int i = 0; i < N; i++) { //先根据成绩把学生排个序(相当于处理录取时候的顺序) for (int j = 2; j < K + 2; j++) { int sumP = studentN[i][0] + studentN[i][1]; int G = studentN[i][0]; students_sort[i] = make_tuple(sumP, G, i); } } sort(students_sort.begin(), students_sort.end(), cmp1); //排好序后,决定了录取的优先顺序 //以下为模拟录取过程 for (int i = 0; i < N; i++) { int node = get<2>(students_sort[i]); //遍历这个学生的各个志愿 for (int j = 2; j < K + 2; j++) { auto sz = AdmissionList[studentN[node][j]].size(); if (sz < schoolN[studentN[node][j]]) { AdmissionList[studentN[node][j]].push_back(students_sort[i]); break; } else { auto &t = AdmissionList[studentN[node][j]].back(); if (IsEqual(students_sort[i], t)) {//如果完全相同则破例录取 AdmissionList[studentN[node][j]].push_back(students_sort[i]); break; } } } } }
void print() { for (int i = 0; i < M; i++) { auto sz = AdmissionList[i].size(); sort(AdmissionList[i].begin(), AdmissionList[i].end(), cmp2);//打印前先编号从小到大排序 for (int j = 0; j < sz; j++) { if (j != sz - 1) { cout << get_val(AdmissionList[i][j]) << ' '; } else cout << get_val(AdmissionList[i][j]); } if (i != M - 1) cout << endl; } }
效率yyds
#include<bits/stdc++.h> using namespace std; int N, M, K; int *schoolN; //存储每个学校的限额 int **studentN; //存储每个学生的分数和志愿 vector<tuple<int, int, int>> students_sort; //这个只是用来排序的工具 vector<tuple<int, int, int>> *AdmissionList;//存储每个学校的录取名单 //@输入和更新数据 void Input() {//先把数据存起来再说 ios::sync_with_stdio(false); cin >> N >> M >> K; schoolN = new int[M]; studentN = new int *[N]; students_sort.resize(N); AdmissionList = new vector<tuple<int, int, int>>[M]; for (int i = 0; i < M; i++) { int x; cin >> x; schoolN[i] = x; } for (int i = 0; i < N; i++) { int n = 2 + K; int *t = new int[n]; for (int j = 0; j < n; j++) { int x; cin >> x; t[j] = x; } studentN[i] = t; } } //@更新答案 bool cmp1(tuple<int, int, int> &a, tuple<int, int, int> &b) { return (get<0>(a) > get<0>(b)) || (get<0>(a) == get<0>(b) && get<1>(a) > get<1>(b)); } inline bool IsEqual(tuple<int, int, int> &a, tuple<int, int, int> &b) { return get<0>(a) == get<0>(b) && get<1>(a) == get<1>(b); } inline int get_val(tuple<int, int, int> &a) { return get<2>(a); } void solve() { for (int i = 0; i < N; i++) { //先根据成绩把学生排个序(相当于处理录取时候的顺序) for (int j = 2; j < K + 2; j++) { int sumP = studentN[i][0] + studentN[i][1]; int G = studentN[i][0]; students_sort[i] = make_tuple(sumP, G, i); } } sort(students_sort.begin(), students_sort.end(), cmp1); //排好序后,就根据这个顺序给学生进行录取 //以下为模拟录取过程 for (int i = 0; i < N; i++) { int node = get<2>(students_sort[i]); for (int j = 2; j < K + 2; j++) { auto sz = AdmissionList[studentN[node][j]].size(); if (sz < schoolN[studentN[node][j]]) { AdmissionList[studentN[node][j]].push_back(students_sort[i]); break; } else { auto &t = AdmissionList[studentN[node][j]].back(); if (IsEqual(students_sort[i], t)) { AdmissionList[studentN[node][j]].push_back(students_sort[i]); break; } } } } } //@打印答案 bool cmp2(tuple<int, int, int> &a, tuple<int, int, int> &b) { return get<2>(a) < get<2>(b); } void print() { for (int i = 0; i < M; i++) { auto sz = AdmissionList[i].size(); sort(AdmissionList[i].begin(), AdmissionList[i].end(), cmp2); for (int j = 0; j < sz; j++) { if (j != sz - 1) { cout << get_val(AdmissionList[i][j]) << ' '; } else cout << get_val(AdmissionList[i][j]); } if (i != M - 1) cout << endl; } } int main() { Input(); solve(); print(); return 0; }
#include <iostream> #include <vector> #include <algorithm> using namespace std; int stu_num,sch_num,cho_num; vector<int> temp1; vector<int> temp2; vector<int> sch; vector<vector<int>> choice; vector<vector<int>> choice1; vector<vector<int>> sch_list; bool cmp(vector<int> i,vector<int> j){ if (i[1]+i[2]!=j[1]+j[2]) { return i[1]+i[2]>j[1]+j[2]; }else return i[1]>j[1]; } int main(int argc, const char * argv[]) { int t; cin>>stu_num>>sch_num>>cho_num; for (int i=0; i<sch_num; i++) { cin>>t; sch.push_back(t); sch_list.push_back(temp1); } for (int i=0; i<stu_num; i++) { temp1.push_back(i); for (int j=0; j<cho_num+2; j++) { cin>>t; temp1.push_back(t); temp2.push_back(t); } choice.push_back(temp1); choice1.push_back(temp2); temp1.clear(); temp2.clear(); } sort(choice.begin(), choice.end(), cmp); for (int i=0; i<stu_num; i++) { for (int j=0; j<cho_num; j++) { if (sch[choice[i][j+3]]>0) { sch_list[choice[i][j+3]].push_back(choice[i][0]); sch[choice[i][j+3]]--; break; }else if(choice1[sch_list[choice[i][j+3]].back()][1]==choice1[choice[i][0]][1]&&choice1[sch_list[choice[i][j+3]].back()][0]==choice1[choice[i][0]][0]){ sch_list[choice[i][j+3]].push_back(choice[i][0]); sch[choice[i][j+3]]--; break; } } } for (int i=0; i<sch_num; i++) { if (sch_list[i].size()!=0) { sort(sch_list[i].begin(), sch_list[i].end()); auto it=sch_list[i].begin(); while (it!=sch_list[i].end()) { cout<<*it; it++; if (it!=sch_list[i].end()) { cout<<" "; }else cout<<endl; } }else cout<<endl; } return 0; }
#include <iostream> #include <algorithm> #include <vector> using namespace std; const int STUDENT_SIZE = 4e4; const int SCHOOL_SIZE = 100; struct student { float exam_grade, final_grade; int ID; vector<int> choice; } s[STUDENT_SIZE]; int _size[SCHOOL_SIZE]; vector<student> admission[SCHOOL_SIZE]; bool cmp1(student a, student b) { if (a.final_grade == b.final_grade) return a.exam_grade > b.exam_grade; return a.final_grade > b.final_grade; } bool cmp2(student a, student b) { return a.ID < b.ID; } int main() { int n, m, k; cin >> n >> m >> k; for (int i = 0; i < m; i++) cin >> _size[i]; for (int i = 0; i < n; i++) { float u, v; cin >> u >> v; s[i].exam_grade = u; s[i].final_grade = (u + v) / 2; s[i].ID = i; for (int j = 0; j < k; j++) { int w; cin >> w; s[i].choice.push_back(w); } } sort(s, s + n, cmp1); for (int i = 0; i < n; i++) { for (int j = 0; j < s[i].choice.size(); j++) { int u = s[i].choice[j]; if (admission[u].size() < _size[u]) { admission[u].push_back(s[i]); break; } else { if (admission[u].back().final_grade == s[i].final_grade && admission[u].back().exam_grade == s[i].exam_grade) { admission[u].push_back(s[i]); break; } } } } for (int i = 0; i < m; i++) { sort(admission[i].begin(), admission[i].end(), cmp2); for (auto t : admission[i]) cout << t.ID << " "; cout << endl; } return 0; }
#include<bits/stdc++.h> #define N 40011 #define K 111 using namespace std; struct node{ int ge,gi,total,rank,num; vector<int> applicant; }data[N]; bool cmp(node n1,node n2){ return n1.total!=n2.total?n1.total>n2.total:n1.ge>n2.ge; } int main(){ int n,k,i,j,m; int q[K]={0}; set<int> admit[K],admitRank[K]; cin>>n>>m>>k; for(i=0;i<=m-1;i++)cin>>q[i]; for(i=0;i<=n-1;i++){ data[i].num=i; cin>>data[i].ge>>data[i].gi; data[i].total=data[i].ge+data[i].gi; data[i].applicant.resize(k); for(j=0;j<=k-1;j++) cin>>data[i].applicant[j]; } sort(data,data+n,cmp); data[0].rank=0; for(i=1;i<=n-1;i++){ if(data[i].total==data[i-1].total&&data[i].ge==data[i-1].ge) data[i].rank=data[i-1].rank; else data[i].rank=i; } for(i=0;i<=n-1;i++){ for(auto it:data[i].applicant) if(q[it]>0){ admit[it].insert(data[i].num); admitRank[it].insert(data[i].rank); q[it]--; break; } else if(admitRank[it].count(data[i].rank)){ admit[it].insert(data[i].num); break; } } for(i=0;i<=m-1;i++,cout<<endl){ if(admit[i].empty())continue; auto it=admit[i].begin(); cout<<*it; for(it++;it!=admit[i].end();it++) cout<<' '<<*it; } return 0; }C++的,主要利用STL
#include<iostream> (720)#include<vector> #include<algorithm> using namespace std; const int maxM = 101; const int maxN = 40001; struct applicant { int number; int GE; int GI; vector<int>priority;//选择学校的先后顺序 applicant(int number, int ge, int gi, vector<int>p) :number(number), GE(ge), GI(gi), priority(p) {} }; bool cmp(applicant a, applicant b) { if (a.GE + a.GI > b.GE + b.GI) { return true; } else if (a.GE + a.GI < b.GE + b.GI) { return false; } else { return a.GE > b.GE; } } int main() { //freopen("C:\\Users\\47\\Desktop\\1.txt", "r", stdin); int n, m, k; cin >> n >> m >> k; vector<applicant>applicants; vector<applicant>tmp; vector<int>school;//每个学校的预留人数 vector<int>school_app[maxM];//每个学校的最终选定人 vector<int>rank;//每个学生排序后的rank排名 for (int i = 0; i < m; i++) { int quota; cin >> quota; school.push_back(quota); } for (int i = 0; i < n; i++) { int GE, GI, p; cin >> GE >> GI; vector<int>tmp; for (int i = 0; i < k; i++) { cin >> p; tmp.push_back(p); } applicants.push_back(applicant(i, GE, GI, tmp)); } tmp = applicants; sort(applicants.begin(), applicants.end(), cmp); for (int i = 0; i < applicants.size(); i++) { applicant one = applicants[i]; for (int j = 0; j < one.priority.size(); j++) { int sc = one.priority[j]; if (school[sc]) { school_app[sc].push_back(one.number); school[sc]--; break; } else { int pre = school_app[sc][school_app[sc].size() - 1];//这里的pre是编号,并不一定对应applicants中的下标19 if (tmp[pre].GE == one.GE && tmp[pre].GI == one.GI) { school_app[sc].push_back(one.number); break; } } } } for (int i = 0; i < m; i++) { sort(school_app[i].begin(),school_app[i].end()); for (int j = 0; j < school_app[i].size(); j++) { if (j) printf(" "); printf("%d", school_app[i][j]); } printf("\n"); } }
//牛客过不了最后一个点,pat全过 #define _CRT_SECURE_NO_WARNINGS (842)#include <iostream> #include <algorithm> (831)#include <cmath> #include <string> (765)#include <vector> #include <set> (855)#include <queue> #include <map> (747)#include <iomanip> #include <sstream> using namespace std; //1080 Graduate Admission //同分同名 //编号均为0开始。 class stu { public: int id, ge, gi, rank; float fg;//final grade vector<int> choices; int result; stu() :ge(0), gi(0), fg(0), result(-2){} }; class col { public: int quota; vector<int> adm; }; col colleges[105] = {}; stu stus[40005]; bool cmp(stu &a, stu&b) { if (a.fg != b.fg) return a.fg > b.fg; else if (a.ge != b.ge) return a.ge > b.ge; else return a.id<b.id; //按号码升序 } int n, m, k; int len; int main() { cin >> n >> m >> k; //数据录入 int quo; for (int i = 0; i < m; ++i) { scanf("%d", &quo); colleges[i].quota = quo; } //学生申请 int e_, i_, c; for (int i = 0; i < n; ++i) { scanf("%d%d", &e_, &i_); stus[i].id = i; stus[i].ge = e_; stus[i].gi = i_; stus[i].fg = float(e_ + i_) / 2; for (int j = 0; j < k; ++j) { scanf("%d", &c); stus[i].choices.push_back(c); } } //排序 sort(stus, stus + n, cmp); //排名更新 stus[0].rank = 0;//rank从第0名开始 for (int i = 1; i < n; ++i) { if (stus[i].gi == stus[i - 1].gi && stus[i].ge == stus[i - 1].ge) stus[i].rank = stus[i - 1].rank; else stus[i].rank = i; } //模拟投递 //先对0号选手做一次 for (int j = 0; j < k; ++j) { int cur_c = stus[0].choices[j]; if (colleges[cur_c].quota > 0) { colleges[cur_c].adm.push_back(stus[0].id); colleges[cur_c].quota--; stus[0].result = cur_c; } break; //录取后不再看后面志愿 } //然后是后面选手 for (int i = 1; i < n; ++i) { for (int j = 0; j < k; ++j) { int cur_c = stus[i].choices[j]; if (colleges[cur_c].quota > 0) { //你被录取了 colleges[cur_c].adm.push_back(stus[i].id); colleges[cur_c].quota--; stus[i].result = cur_c; break;//录取后不再看后面志愿 } else if (stus[i].rank == stus[i - 1].rank && cur_c == stus[i - 1].result) { //同分挤进去,你被录取了 colleges[cur_c].adm.push_back(stus[i].id); colleges[cur_c].quota--; stus[i].result = cur_c; break; } } } //输出结果 for (int i = 0; i < m; ++i) { len = colleges[i].adm.size(); if (len == 0) { cout << endl; continue; } //若不为0还需要内部排序一次 sort(colleges[i].adm.begin(), colleges[i].adm.end(), less<int>()); cout << colleges[i].adm[0]; for (int j =1; j < len; ++j) { cout << " " << colleges[i].adm[j]; } cout << endl; } return 0; }
a = list(map(int,input().split())) b = list(map(int,input().split())) c = [list(map(int,input().split())) + [i]for i in range(a[0])] m,p = [[] for i in b],[] for i in sorted(c,key = lambda x:[sum(x[:2]),x[0]])[::-1]: for j in i[2:-1]: if b[j] > 0 or [sum(i[:2]),i[0],j] == p: m[j].append(i[-1]) b[j],p = b[j] - 1,[sum(i[:2]),i[0],j] break print("\n".join([' '.join(map(str,sorted(i))) for i in m]))
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; struct _rank{ int id; int g; int ge; _rank(int _id=0,int _g=0,int _ge=0){ id =_id; g =_g; ge =_ge; } }; bool cmp(_rank &a,_rank &b){ if(a.g!=b.g) return a.g>b.g; else return a.ge>b.ge; } bool cmp2(int a,int b){ return a<b; } int main() { int n,m,k; scanf("%d %d %d",&n,&m,&k); int quota[m]; for(int i=0;i<m;i++){ int t; scanf("%d",&t); quota[i]=t; } _rank rk[n+1]; for(int i=0;i<=n;i++) rk[i] =_rank(0,0,0); int target[n][k]; for(int i=0;i<n;i++) for(int j=0;j<k;j++) target[i][j] =0; for(int i=0;i<n;i++){ int g1,g2; scanf("%d %d",&g1,&g2); rk[i].ge=g1; rk[i].g=g1+g2; rk[i].id=i; for(int j=0;j<k;j++){ int a; scanf("%d",&a); target[i][j]=a; } } sort(rk,rk+n,cmp); int r[n]; for(int i=0;i<n;i++) r[i] =0; int s=0; r[rk[0].id] =0; for(int i=1;i<n;i++){ if(!(rk[i].g==rk[i-1].g&&rk[i].ge==rk[i-1].ge)) s++; r[rk[i].id] =s; } int adm[m][n+1]; for(int i=0;i<m;i++) for(int j=0;j<=n;j++) adm[i][j] =-1; int len[m],r2[m]; for(int i=0;i<m;i++){ len[i] =0; r2[i] =-1; } for(int i=0;i<n;i++){ int t=rk[i].id; for(int j=0;j<k;j++){ int a=target[t][j]; if(len[a]<quota[a]||(r2[a]!=-1&&r2[a]==r[t])){ adm[a][len[a]] =t; len[a]++; if(len[a]==quota[a]) r2[a] =r[t]; break; } } } for(int i=0;i<m;i++){ int t =len[i]; if(t>0){ sort(&adm[i][0],&adm[i][0]+t,cmp2); printf("%d",adm[i][0]); for(int j=1;adm[i][j]!=-1;j++){ int a=adm[i][j]; printf(" %d",a); } } printf("\n"); } return 0; }
#include <iostream> #include <vector> #include <functional> #include <algorithm> #include <cmath> using namespace std; struct Grade{ int id; int ge; int gi; Grade(int id, int ge, int gi): id(id), ge(ge), gi(gi){} }; bool operator >(const Grade& lhs, const Grade& rhs){ double ls = (lhs.ge + lhs.gi) / 2.0; double rs = (rhs.ge + rhs.gi) / 2.0; if(std::fabs(ls - rs) < 1e-5){ return lhs.ge > rhs.ge; } return ls > rs; } bool operator ==(const Grade& lhs, const Grade& rhs){ double ls = (lhs.ge + lhs.gi) / 2.0; double rs = (rhs.ge + rhs.gi) / 2.0; return (std::fabs(ls - rs) < 1e-5 && lhs.ge == rhs.ge); } int main(){ int N, M, K; cin >> N >> M >> K; vector<int> quotas(M); for(int i = 0; i < M; i++){ cin >> quotas[i]; } vector<vector<int>> apts(N); vector<Grade> grades; for(int i = 0; i < N; i++){ int ge, gi; cin >> ge >> gi; for(int j = 0; j < K; j++){ int school; cin >> school; apts[i].push_back(school); } grades.emplace_back(i, ge, gi); } sort(begin(grades), end(grades), greater<Grade>{}); vector<vector<Grade>> accepted(M); for(auto& g : grades){ for(auto sc : apts[g.id]){ if( (int)accepted[sc].size() < quotas[sc] || (!accepted[sc].empty() && accepted[sc].back() == g) ){ accepted[sc].push_back(g); break; } } } vector<int> ids; for(auto& gs : accepted){ ids.clear(); for(auto& g : gs){ ids.push_back(g.id); } sort(begin(ids), end(ids)); for(int i = 0; i < (int)ids.size(); i++){ if(i) cout << " "; cout << ids[i]; } cout << endl; } }
#include<iostream> #include<stdio.h> #include<algorithm> #include<vector> #define sum(i) i.s1 + i.s2 using namespace std; struct School { int minRank; //录取的最低排名 int stuNum; //计划收取的学生数 vector<int> stu; //录取的学生 }; struct Student{ int index; //学生编号 int s1, s2; //科目一和科目二分数 int rank; //排名 int choose[6]; //志愿 }; int stuNum, schNum, choNum; bool func(Student &a, Student &b){ if (sum(a) != sum(b)) return sum(a) > sum(b); return a.s1 > b.s1; } School school[101]; Student student[40001]; int main(){ scanf("%d%d%d", &stuNum, &schNum, &choNum); for (int i = 0; i < schNum; i++) scanf("%d", &school[i].stuNum); for (int i = 0; i < stuNum; i++){ student[i].index = i; scanf("%d%d", &student[i].s1, &student[i].s2); for (int j = 0; j < choNum; j++) scanf("%d", &student[i].choose[j]); } sort(student, student + stuNum, func); student[0].rank = 1; //为学生成绩排名 for (int i = 1; i < stuNum; i++) { if (sum(student[i]) == sum(student[i - 1]) && student[i].s1 == student[i - 1].s1) { student[i].rank = student[i - 1].rank; } else{ student[i].rank = student[i - 1].rank + 1; } //cout << "------->" <<i << " " << student[i].rank << endl; } //学生选择学校 for (int i = 0; i < stuNum; i++){ for (int j = 0; j < choNum; j++) { int want = student[i].choose[j]; if (school[want].stuNum > 0 || school[want].minRank == student[i].rank){ school[want].stu.push_back(student[i].index); school[want].stuNum--; school[want].minRank = student[i].rank; break; } } } //输出录取状况 for (int i = 0; i < schNum; i++){ sort(school[i].stu.begin(), school[i].stu.end()); if (school[i].stu.empty()) { cout << endl; continue; } cout << school[i].stu[0]; for (int j = 1; j < school[i].stu.size(); j++) cout <<" "<<school[i].stu[j] ; cout << endl; } }
没什么难度,直接排序就行
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
struct student {
int id, ge, gi;
int choices[5];
friend bool operator==(const student& s1, student& s2) {
return s1.ge == s2.ge && s1.gi == s2.gi;
}
} apps[40000 + 5];
int order[40000 + 5]; // use id to find sorted order
int schools[105];
int n, m, k;
bool cmp(student s1, student s2) {
int f1 = s1.ge + s1.gi, f2 = s2.ge + s2.gi;
if (f1 != f2) {
return f1 > f2;
}
return s1.ge > s2.ge;
}
int main() {
scanf("%d%d%d", &n, &m, &k);
vector<int> quotas[m];
for (int i = 0; i < m; i++) {
scanf("%d", &schools[i]);
}
for (int i = 0; i < n; i++) {
apps[i].id = i;
scanf("%d%d", &apps[i].ge, &apps[i].gi);
for (int j = 0; j < k; j++) {
scanf("%d", &apps[i].choices[j]);
}
}
sort(apps, apps + n, cmp);
for (int i = 0; i < n; i++) {
order[apps[i].id] = i;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
int choice = apps[i].choices[j];
if (schools[choice] != 0) {
quotas[choice].push_back(apps[i].id);
schools[choice]--;
break;
} else {
// same app
student s = apps[order[quotas[choice][quotas[choice].size() - 1]]];
if (apps[i] == s) {
quotas[choice].push_back(apps[i].id);
break;
}
}
}
}
for (int i = 0; i < m; i++) {
if (quotas[i].size() == 0) {
printf("\n");
} else {
sort(quotas[i].begin(), quotas[i].end());
for (int j = 0; j < quotas[i].size(); j++) {
if (j != 0) printf(" ");
printf("%d", quotas[i][j]);
}
if (i != m - 1) printf("\n");
}
}
return 0;
}
ranklst = [] n,m,k = map(int,input().split()) #boolst = [True for i in range(n)] out = [[] for i in range(m)] dinge = list(map(int,input().split())) lst = [] for i in range(n): te = list(map(int,input().split())) te.append(i) lst.append(te) lst.sort(key=lambda x:(-x[0]-x[1],-x[0])) ran,ran1 = 0,1 for i in range(0,len(lst)-1): lst[i].append(ran) for j in range(i+1,len(lst)): if lst[i][0]==lst[j][0] and (lst[i][0]+lst[i][1])==(lst[j][0]+lst[j][1]): ran1+=1 break else: ran+=ran1 ranklst.append(i+1) ran1=1 break lst[len(lst)-1].append(ran) ranklst.append(n) ranklst = [0]+ranklst backup = list(lst) #如果是学校挑人的话: #for i in range(2,2+k): # #同一排名的输入 # for j in range(0,len(ranklst)-1): # for l in range(ranklst[j],ranklst[j+1]): # if boolst[l]: # te = set([]) # if dinge[lst[l][i]]>0 or (lst[l][i] in te): # te.add(lst[l][i]) # out[lst[l][i]].append(str(lst[l][-2])) # boolst[l]=False # dinge[lst[l][i]]-=1 con=0 for i in range(0,len(ranklst)-1): te = set([]) for j in range(ranklst[i],ranklst[i+1]): for l in range(2,2+k): if dinge[lst[j][l]]>0 or (lst[j][l] in te): te.add(lst[j][l]) out[lst[j][l]].append(lst[j][-2]) dinge[lst[j][l]]-=1 lst[j].append(False) con+=1 break while con: for i in lst: if not i[-1]: lst.remove(i) con-=1 if lst: ranka= [] lst.sort(key=lambda x:(-x[0]-x[1],-x[0])) ran,ran1 = 0,1 for i in range(0,len(lst)-1): lst[i].append(ran) for j in range(i+1,len(lst)): if lst[i][0]==lst[j][0] and (lst[i][0]+lst[i][1])==(lst[j][0]+lst[j][1]): ran1+=1 break else: ran+=ran1 ranka.append(i+1) ran1=1 break lst[len(lst)-1].append(ran) ranka.append(len(lst)) ranka = [0]+ranka for i in range(0,len(ranka)-1): te = set([]) for j in range(ranka[i],ranka[i+1]): for l in range(2,2+k): if dinge[lst[j][l]]>0 or (lst[j][l] in te): te.add(lst[j][l]) out[lst[j][l]].append(lst[j][-2]) dinge[lst[j][l]]-=1 # lst[j].append(False) break for i in out: if i: i.sort() print(' '.join(map(str,i))) else: print()这道题注意,是学生排名由高到低来挑学校,而不是学校按学生排名来挑学生。