PAT A1080 Gradate Admission

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;
} 


你可能感兴趣的:(C++,算法,pat)