PAT A1080 Gradute Admission
不懂我自己的4分错在哪里,这是我的版本
//靠自己的力量得到了26分,但是还有4分的坑不知道在哪里 //我自己的方法就是变量有点乱,其实可以再加一个结构体school的 #include<cstdio> #include<cstring> #include<algorithm> //#define LOCAL using namespace std; struct Student{ int id;//0~N-1; int ge,gi; int socre_all; int choice[6];//k<=5 int rank; }stu[40010]; bool cmp(Student a,Student b){ if(a.socre_all!=b.socre_all) return a.socre_all>b.socre_all; if(a.ge!=b.ge) return a.ge>b.ge; else return a.id<b.id; } int squota[110];//就当做100个学校 int quantity[110];//每个学校的当前录取学生数,如果rank一样且申请一样,则都录取 int match[110][40001];//存放被录取的每个学生的id int main(){ #ifdef LOCAL freopen("A1080data.in","r",stdin); freopen("A1080data.out","w",stdout); #endif int n,m,k; //quantity[110];静态变量不可以这样赋值,必须用memset memset(quantity,0,sizeof(int)); scanf("%d%d%d",&n,&m,&k);//n个学生,m所学校,k个选择 for(int i=0;i<m;i++){ scanf("%d",&squota[i]);//输入每个学校的定额 } for(int i=0;i<n;i++){ scanf("%d%d%",&stu[i].ge,&stu[i].gi); stu[i].socre_all=(stu[i].ge+stu[i].gi)/2; stu[i].id=i; for(int j=0;j<k;j++){ scanf("%d",&stu[i].choice[j]);//这个不一定是3个的,几个是右k决定的 } } sort(stu,stu+n,cmp);//按成绩从高到低,成绩相同,则按笔试分数,如果笔试分数还相同,则按照学号,但是rank必须相同 stu[0].rank=1; for(int i=1;i<n;i++){ if(stu[i].socre_all==stu[i-1].socre_all&&stu[i].ge==stu[i-1].ge){ stu[i].rank=stu[i-1].rank; } else stu[i].rank=i+1; } //录取可能要用到二重循环 int temp; for(int i=0;i<n;i++){ for(int j=0;j<k;j++){ temp=stu[i].choice[j];//表示当前选择学校的id if(quantity[temp]<squota[temp]){ match[temp][quantity[temp]]=stu[i].id;//把这个学生的Id放到match[学校id][学校实际数量],从0开始的 quantity[temp]++;//是相当于n break; } else if(stu[match[temp][quantity[temp]-1]].rank==stu[i].rank){ match[temp][quantity[temp]]=stu[i].id; quantity[temp]++; break; } } } //现在对每个match进行排序 for(int i=0;i<m;i++){ sort(match[i],match[i]+quantity[i]);//升序排列 } for(int i=0;i<m;i++){ for(int j=0;j<quantity[i];j++){ if(j!=0) printf(" "); printf("%d",match[i][j]); } printf("\n"); } return 0; }
这是参考书的版本,提交上去就是ac,气死了
//我去!这个参考书的版本全部正确,但是我不懂我那个错在哪里! #include<cstdio> #include<cstring> #include<algorithm> //#define LOCAL using namespace std; struct Student{ int GE,GI,sum; int r,stuID; int cho[6]; }stu[40010]; struct School{ int quota;//定额 int stuNum;//当前实际招生人数 int id[40010];//招收的学生编号 int lastAdmit;//记录最后一个招收的学生的编号 }sch[110]; bool cmpStu(Student a,Student b){ if(a.sum!=b.sum) return a.sum>b.sum; else return a.GE>b.GE; } bool cmpID(int a,int b){ return stu[a].stuID<stu[b].stuID; } int main(){ #ifdef LOCAL freopen("A1080data.in","r",stdin); freopen("A1080data.out","w",stdout); #endif int n,k,m; scanf("%d%d%d",&n,&m,&k); for(int i=0;i<m;i++){ scanf("%d",&sch[i].quota); sch[i].stuNum=0; sch[i].lastAdmit=-1;//注意这里哈!输出的时候这里是-1的话应该直接输出换行符吧 } for(int i=0;i<n;i++){ stu[i].stuID=i; scanf("%d%d",&stu[i].GE,&stu[i].GI); stu[i].sum=stu[i].GE+stu[i].GI; for(int j=0;j<k;j++){ scanf("%d",&stu[i].cho[j]);//注意这里的k是不定的 } } sort(stu,stu+n,cmpStu);//对n个考生成绩排序 for(int i=0;i<n;i++){ if(i>0&&stu[i].sum==stu[i-1].sum&&stu[i].GE==stu[i-1].GE){ stu[i].r=stu[i-1].r; } else stu[i].r=i; } //开始匹配 for(int i=0;i<n;i++){ for(int j=0;j<k;j++){ int choice=stu[i].cho[j]; int num=sch[choice].stuNum;//选择学校的当前招生人数 int last=sch[choice].lastAdmit; //如果人数未满护着改学校的最后一个考生与该考生的排名相同 if(num<sch[choice].quota||(last!=-1&&stu[i].r==stu[last].r)){ sch[choice].id[num]=i; sch[choice].lastAdmit=i;//该学校的最后一个,本来按照自己的理解,这里应该写stu[i].id,不知道这里居然写这个,而且调试是对的 sch[choice].stuNum++; break; } } } for(int i=0;i<m;i++){ if(sch[i].stuNum>0){ //如果有招到学生 sort(sch[i].id,sch[i].id+sch[i].stuNum,cmpID); for(int j=0;j<sch[i].stuNum;j++){ printf("%d",stu[sch[i].id[j]].stuID); if(j<sch[i].stuNum-1){ printf(" "); } } } printf("\n"); } return 0; }