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;
}
本文详细解读了PATA1080GraduteAdmission问题的解决策略,通过比较两种不同的代码实现版本,深入探讨了如何优化代码结构、提高效率,并针对错误代码进行了详细的分析与修正建议。
6万+

被折叠的 条评论
为什么被折叠?



