题解 | #奥运排序问题#
奥运排序问题
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
//慢慢排错,最终才发现少考虑了金牌/奖牌数量相等的情况:排名应该并列
腾讯成长空间 5893人发布
