1080 Graduate Admission

大致题意就是有N个学生,有M个学校,每个学校的名额都是正整数。每个学生可以填K个学校志愿,N个学生一起排名以后,排名高的学生先挑学校,不保护一志愿。

题目要求:

首先,把所有学生按总成绩SUM(GE+GI)递减排序,如果SUM相同,那么就按GE递减排序。

然后,根据成绩确定所有学生的名次。如果当前学生与上一个学生的SUM和GE相同,那么当前学生与上一个学生的名次也相同。

确定所有学生的名次以后,从排名第一名的学生的第一个志愿学校开始。

如果该学校有名额,或者该学校没名额了但是该学生与该学校录取的最后一个学生的名次一样,那么就录取这名学生。

否则,该学生继续找下一个志愿学校,直到能找到能被录取的学校(该学校名额减一),或者所有志愿学校找完都无法被录取。

所有学生的志愿学校都找完以后,每个学校按要求递增输出学生编号。(具体不再赘述)

 

STL:set容器及其函数,sort函数,auto智能指针。

注意点:学生排序以后,学生id与数组i可能不一致了。代码中的last应该存放i(当前访问的学生),而不是学生id。

 1 #include"iostream"
 2 #include"set"
 3 #include"algorithm"
 4 using namespace std;
 5 struct Student {
 6     int GE,GI,SUM;//考研成绩,面试成绩,总分 
 7     int id;//学生编号
 8     int RANK;//排名
 9     int choices[6];//k<=5个志愿
10 } stu[40010];
11 
12 struct School {
13     int quota;//学校名额
14     set<int> ID;//录取学生编号,set可以自动排序
15     int last = -1;//标记最后一个被录取学生的编号
16 } sch[200];
17 
18 bool cmp(const Student& a,const Student& b) { //采用引用变量执行更快
19     if(a.SUM != b.SUM)
20         return a.SUM > b.SUM;
21     else
22         return a.GE > b.GE;
23 }
24 
25 int main() {
26     int N,M,K;
27     scanf("%d%d%d",&N,&M,&K);
28     for(int i = 0; i < M; ++i) {
29         scanf("%d",&sch[i].quota);
30     }
31     for(int i = 0; i < N; ++i) {
32         scanf("%d%d",&stu[i].GE,&stu[i].GI);
33         for(int j = 0; j < K; ++j) {//K个志愿
34             scanf("%d",&stu[i].choices[j]);
35         }
36         stu[i].id = i;//学生id
37         stu[i].SUM = stu[i].GE + stu[i].GI;//总成绩
38     }
39     sort(stu,stu+N,cmp);//对学生进行排名,排序以后id与i就可能不一致了 
40     for(int i = 0 ; i < N; ++i) {//设置每个学生的名次
41         if(i > 0 && stu[i].SUM == stu[i-1].SUM && stu[i].GE == stu[i-1].GE) //如果两个学生的SUM和GE相同,那么他们的名次也相同
42             stu[i].RANK = stu[i-1].RANK;
43         else
44             stu[i].RANK = i;
45     }
46     for(int i = 0; i < N; ++i) {
47         for(int j = 0; j < K; ++j) {
48             int choice = stu[i].choices[j];//当前学生的当前志愿
49             int last = sch[choice].last;//最后一个被录取的学生
50             //学校有名额,或者该学校录满了但该学生与已录取的最后一个学生的名次一样时
51             if(sch[choice].quota > 0 || stu[i].RANK == stu[last].RANK) {
52                 sch[choice].ID.insert(stu[i].id);//录入学生 id
53                 sch[choice].last = i;//记录当前访问了的学生,之前i写成了stu[i].id导致测试点1,2未通过,妹的!!!  
54                 sch[choice].quota--;//名额减一
55                 break;
56             }
57         }
58     }
59     for(int i = 0; i < M; ++i) {
60         int t = sch[i].ID.size();
61         if(t > 0) {
62             //auto 是C++11里面的新特性,可以让编译器根据初始值类型直接推断变量的类型
63             for(auto it = sch[i].ID.begin(); it!=sch[i].ID.end(); ++it) {
64                 printf("%d",*it);
65                 if(t-- > 1) {
66                     printf(" ");
67                 }
68             }
69         }
70         printf("\n");
71     }
72     return 0;
73 }

 

 

  

posted @ 2020-02-11 00:12  tangq123  阅读(331)  评论(0)    收藏  举报