带模拟,但不算太难,感觉给(30)分水了。
对于每位考生的每个志愿学校,如果当前志愿学校的招生人数未达到该校招生人数总额度或该校上一个录取考生的排名与该考生的排名相同,则不受招生人数限制,破格录取该考生。
对每个学校,将其录取考生按编号从小到大排序,并按学校的顺序输出录取考生的编号。
排序要按双关键字排,不能只按总分排,否则计算出的(rank)会与题意描述的不同。
const int N=40010;
struct Node
{
int id;
int ge,gi;
int sum;
int rank;
int choose[5];
bool operator<(const Node &W) const
{
if(sum == W.sum) return ge > W.ge;
return sum > W.sum;
}
}a[N];
int quota[110];
vector<Node> school[110];
int n,m,k;
bool cmp(Node &a,Node &b)
{
return a.id < b.id;
}
int main()
{
cin>>n>>m>>k;
for(int i=0;i<m;i++) cin>>quota[i];
for(int i=0;i<n;i++)
{
a[i].id=i;
cin>>a[i].ge>>a[i].gi;
a[i].sum=a[i].ge+a[i].gi;
for(int j=0;j<k;j++) cin>>a[i].choose[j];
}
sort(a,a+n);
for(int i=0;i<n;i++)
{
if(i && a[i].sum == a[i-1].sum && a[i].ge == a[i-1].ge)
a[i].rank=a[i-1].rank;
else
a[i].rank=i+1;
for(int j=0;j<k;j++)
{
int k=a[i].choose[j];
if(school[k].size() < quota[k] || a[i].rank == school[k].back().rank)
{
school[k].pb(a[i]);
break;
}
}
}
for(int i=0;i<m;i++)
{
sort(school[i].begin(),school[i].end(),cmp);
for(int j=0;j<school[i].size();j++)
if(j) cout<<' '<<school[i][j].id;
else cout<<school[i][j].id;
cout<<endl;
}
//system("pause");
return 0;
}