这道三十分的大题,看起来确实很长,但是其实思路不难,做题再细心一点就可以了,本题类似高考的平行志愿填法,这样我们可以很快理解题意,按照分数高低填报志愿,择高录取,同时,如果说同分但是笔试成绩不同,那么择笔试成绩高者录取,我们根据这个将学生成绩进行排列,注意到如果报考同一学校的学生笔试总分都相同,那么这样的学生都要录取,我们可以再设置一个关于学校的录取最低分数,这样判断是否录取有两个条件1、该校人数不够,那么可以进2、学校人数够,但是各项都达到学校的最低线,也可以加入学校,最后再按照学校的顺序,输出学校录取的学生的id就好了
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
const int maxn=40010;
struct stu
{
int ge,gi,K[5],gtotal,id;
}a[maxn];
struct school
{
int gemin,gtotalmin,total,temp;
int id[maxn];
}s[110];
bool cmp(stu b,stu c)
{
if (b.gtotal!=c.gtotal) return b.gtotal>c.gtotal;
else return b.ge>c.ge;
}
bool cmp2(int b,int c)
{
return b<c;
}
int main()
{
int n,m,k,num,choice;
cin>>n>>m>>k;
for (int i=0;i<m;i++)
{
scanf("%d",&s[i].total);
s[i].gemin=-1;
s[i].gtotalmin=-1;
s[i].temp=0;
}
for (int i=0;i<n;i++)
{
scanf("%d %d",&a[i].ge,&a[i].gi);
a[i].gtotal=a[i].ge+a[i].gi;
a[i].id=i;
for (int j=0;j<k;j++)
{
scanf("%d",&a[i].K[j]);
}
}
sort(a,a+n,cmp);
for (int i=0;i<n;i++)
{
bool flag=false;
for (int j=0;j<k;j++)
{
choice=a[i].K[j];
num=s[choice].temp;
if(s[choice].temp>=s[choice].total)
{
if(a[i].ge==s[choice].gemin&&a[i].gtotal==s[choice].gtotalmin)
{
s[choice].id[num++]=a[i].id;
s[choice].temp++;
flag=true;
}
}
else
{
s[choice].id[num++]=a[i].id;
s[choice].temp++;
s[choice].gemin=a[i].ge;
s[choice].gtotalmin=a[i].gtotal;
flag=true;
}
if (flag==true)
break;
}
}
for (int i=0;i<m;i++)
{
sort(s[i].id,s[i].id+s[i].temp,cmp2);
if(s[i].temp==0)
printf("\n");
else
{
for (int j=0;j<s[i].temp;j++)
{
printf("%d",s[i].id[j]);
if (j!=s[i].temp-1)
printf(" ");
else
printf("\n");
}
}
}
}