题解 | #奥运排序问题#
奥运排序问题
https://www.nowcoder.com/practice/100a4376cafc439b86f5f8791fb461f3
//不知道为什么和标准答案不一样 //方法1:对比与正确输出的区别,猜测问题所在 //方法2:输出错误处的上下全部结果,找出与正确答案的区别 #include <iostream> #include <algorithm> using namespace std; struct gj{ int id;//国家号0~n-1 int a,b;//金牌总数,奖牌总数 int c;//人口百万数(可能为0) double ar,br;//金牌、奖牌比例 int ark,brk;//金牌总数排名,奖牌总数排名 int acrk,bcrk;//金牌人口比例排名,奖牌人口比例排名 }; struct otpt{ int rk;//排名 int way;//排名方式 }; bool cmpa(gj x,gj y)//求金牌排名 { return x.a>y.a; } bool cmpb(gj x,gj y)//求奖牌排名 { return x.b>y.b; } bool cmpark(gj x,gj y)//求金牌人口比例排名 { return x.ar>y.ar; } bool cmpbrk(gj x,gj y)//求金牌人口比例排名 { return x.br>y.br; } bool cmpop(otpt x,otpt y)//求最优排名方式 { if(x.rk==y.rk) return x.way<y.way; else return x.rk<y.rk; } int main() { int n,m; gj rank[200]; while (cin >> n >> m) { for(int i=0;i<n;i++) { cin>>rank[i].a>>rank[i].b>>rank[i].c; rank[i].id=i; } int mm[200]; for(int i=0;i<m;i++) { cin>>mm[i];//要求排名的国家号全部放入mm数组 } //算排名 //录入金牌总数排名 sort(rank,rank+n,cmpa); for(int i=0;i<n;i++) { if(i!=(0)) { if(rank[i].a==rank[i-1].a)//一开始没注意到金排数量相等的情况,后来通过输出某个错误答案 国家的4种排名才发现了错误 { rank[i].ark=rank[i-1].ark; } else { rank[i].ark=i+1; } } else rank[0].ark=1; } //录入奖牌总数排名 sort(rank,rank+n,cmpb); for(int i=0;i<n;i++) { if(i!=(0)) { if(rank[i].b==rank[i-1].b) { rank[i].brk=rank[i-1].brk; } else { rank[i].brk=i+1; } } else rank[0].brk=1; } //录入金牌人口比例排名 for(int i=0;i<n;i++) { if((rank[i].a!=0)&&(rank[i].c!=0)) { double temp=(rank[i].a/1.0)/(rank[i].c/1.0); rank[i].ar=temp; } else if((rank[i].a!=0)&&(rank[i].c==0)) { rank[i].ar=999.9; } else if((rank[i].a==0)&&(rank[i].c!=0)) { rank[i].ar=0; } else{ rank[i].ar=0; } } sort(rank,rank+n,cmpark); for(int i=0;i<n;i++) { if(i!=(0)) { if(rank[i].ar==rank[i-1].ar) { rank[i].acrk=rank[i-1].acrk; } else { rank[i].acrk=i+1; } } else rank[0].acrk=1; } //录入奖牌人口比例排名 for(int i=0;i<n;i++) { if((rank[i].b!=0)&&(rank[i].c!=0)) { double temp=(rank[i].b/1.0)/(rank[i].c/1.0); rank[i].br=temp; } else if((rank[i].b!=0)&&(rank[i].c==0)) { rank[i].br=999.9; } else if((rank[i].b==0)&&(rank[i].c!=0)) { rank[i].br=0; } else{ rank[i].br=0; } } sort(rank,rank+n,cmpbrk); for(int i=0;i<n;i++) { if(i!=(0)) { if(rank[i].br==rank[i-1].br) { rank[i].bcrk=rank[i-1].bcrk; } else { rank[i].bcrk=i+1; } } else rank[0].bcrk=1; } //输出排名 for(int i=0;i<m;i++)//输出m行 { for(int j=0;j<n;j++) { if(rank[j].id==mm[i])//现在要对国家号为rank[j].id的国家输出 { //先比较哪种排名最有利 otpt temp[4]; temp[0].rk=rank[j].ark;temp[0].way=1; temp[1].rk=rank[j].brk;temp[1].way=2; temp[2].rk=rank[j].acrk;temp[2].way=3; temp[3].rk=rank[j].bcrk;temp[3].way=4; sort(temp,temp+4,cmpop); cout<<temp[0].rk<<":"<<temp[0].way<<endl; break; } } } cout<<endl; } } //18:30整整写到22:32 //慢慢排错,最终才发现少考虑了金牌/奖牌数量相等的情况:排名应该并列