一定要先好好看题目!题目!题目!!!!!!!!
我一开始分析错误,没有理解究竟是怎么录取学生的,从学校遍历了一遍,又从志愿遍历了一遍,然而事实上是从学生开始遍历,呜呜呜,这是有史以来写过最长时间的一次。
题目不难,所以前期一定要分析清楚题目,好好读题,浪费不了多少时间的,一定要理解题目,qaq,委屈。重写了三四次,最后一次写的时候看了题目,才知道自己理解的录取方式有问题,最后换成了遍历学生,然后,一遍过,嘤嘤嘤,下次一定要好好读题
以下附上代码和一部分注释
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
//#include<bits/stdc++.h>
struct ID
{
int id=-1,ge=0,gi=0,score=0;
int s[10]={0},rank=0;//意向学校 总排名
}id[41000];
int school[110]={0};//学校计划招生人数
int sch[110]={0};//学校剩余招生人数
int stu1[110][41000]={0};//中间变量
int rank_[110]={0};
bool cmp(ID a,ID b)
{
if(a.score!=b.score) return a.score>b.score;
return a.ge>b.ge;
}
bool cmp2(int a,int b)
{
if(a!=-1&&b!=-1) return a<b;
else return a>b;
}
using namespace std;
int main()
{
int n,m,k;//n 总人数 m 总学校数 k 能选择的学校数目
memset(stu1,-1,sizeof(stu1));
cin>>n>>m>>k;
for(int i=0;i<m;i++)
{
cin>>school[i];
sch[i]=school[i];
}
for(int i=0;i<n;i++)
{
id[i].id=i;
cin>>id[i].ge>>id[i].gi;
id[i].score=id[i].ge+id[i].gi;
for(int j=0;j<k;j++)
cin>>id[i].s[j];//喜欢的学校的名称
}
sort(&id[0],&id[n],cmp);
for(int i=0;i<n;i++)//排名
{
if(i==0) id[i].rank=i+1;
else
{
if(id[i].score==id[i-1].score&&id[i].ge==id[i-1].ge) id[i].rank=id[i-1].rank;
else id[i].rank=i+1;
}
}
//从第一个学生开始遍历,按照志愿录取
for(int i=0;i<n;i++)
{
for(int j=0;j<k;j++)//第一志愿是否符合要求
{
int school_name=id[i].s[j];
int num1=school[school_name];//实际招生人数
int num=num1-sch[school_name];//第num个录取的人数
if(sch[school_name]>0)//存在名额 这一定要写>0 不能写=0 因为有可能是负数
{
stu1[school_name][num]=id[i].id;
rank_[school_name]=id[i].rank;
sch[school_name]--;
break;
}
else
{
if(rank_[school_name]==id[i].rank)
{
stu1[school_name][num]=id[i].id;
rank_[school_name]=id[i].rank;
sch[school_name]--;
break;
}
}
}
}
for(int i=0;i<m;i++)
{
sort(&stu1[i][0],&stu1[i][41000],cmp2);
for(int j=0;stu1[i][j]!=-1;j++)
{
if(j==0)cout<<stu1[i][j];
else cout<<" "<<stu1[i][j];
}
cout<<endl;
}
}
孩子很激动,我不管,我就要放上AC 截图,委屈