题目链接:点击打开链接
题目大意:模拟高考志愿入选规则。
解题思路:先按照优先gf、次要g1降序排序,接着遍历每个申请书中的每个志愿(按顺序),如果还有名额,则入选;如果没名额,判断下是否与最新的该学校的入选的最低成绩gf、g1比较,如果相等,则入选,否则失败并且标记下再也没人可以进入该学校,因为剩下的成绩肯定不如该成绩的申请者。最后需要注意精度控制的问题。
AC 代码
usingnamespacestd; typedeflonglongll; constintmaxn=4e4+10; structpeo{ intg1,g2,id; doublegf; intsch[10]; }ps[maxn]; structsch{ doublegf; intg1,open; }schs[110]; intn,k,m; intcnt[110]; set<int>st[110]; intcmp(peop1,peop2) { if(fabs(p1.gf-p2.gf)<1e-4) returnp1.g1>p2.g1; returnp1.gf>p2.gf; } intmain() { intg1,g2,id; scanf("%d%d%d",&n,&m,&k); for(inti=0;i<m;i++) scanf("%d",&cnt[i]); for(inti=0;i<n;i++) { scanf("%d%d",&g1,&g2); ps[i].g1=g1, ps[i].g2=g2, ps[i].gf=(g1+g2)/2.0, ps[i].id=i; for(intj=0;j<k;j++) scanf("%d",&id), ps[i].sch[j]=id; } sort(ps,ps+n,cmp); for(inti=0;i<n;i++) { for(intj=0,f=0;j<k;j++) { id=ps[i].sch[j]; if(cnt[id]>0) { cnt[id]--; st[id].insert(ps[i].id); schs[id].g1=ps[i].g1; schs[id].gf=ps[i].gf; f=1; } elseif(cnt[id]==0&&!schs[id].open) { if(fabs(schs[id].gf-ps[i].gf)<1e-4&&schs[id].g1==ps[i].g1) st[id].insert(ps[i].id), f=1; elseschs[id].open=1; // 有一个入选失败了的话,剩下的再也不可能有相等rank的情况 } if(f) break; } } for(inti=0;i<m;i++) { if(st[i].size()==0) puts(""); else { intans=0, len=st[i].size(); for(autoit:st[i]) printf("%d%c",it,ans++==len-1?'\n':' '); } } return0; }