1007.奥运排序问题

题目描述:
按要求,给国家进行排名。
输入:
有多组数据。
第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。
第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。
接下来一行给出M个国家号。
输出:
排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例
对每个国家给出最佳排名排名方式 和 最终排名
格式为: 排名:排名方式
如果有相同的最终排名,则输出排名方式最小的那种排名,对于排名方式,金牌总数 < 奖牌总数 < 金牌人口比例 < 奖牌人口比例
如果有并列排名的情况,即如果出现金牌总数为 100,90,90,80.则排名为1,2,2,4.
每组数据后加一个空行。
样例输入:
4 4
4 8 1
6 6 2
4 8 2
2 12 4
0 1 2 3
4 2
8 10 1
8 11 2
8 12 3
8 13 4
0 3
样例输出:
1:3
1:1
2:1
1:2

1:1

1:1


这里要稍微注意一下怎么处理并列排名的情况:对于正常的下标0 1 2 3 ,排名应该是为1 2 3 4 ,即为i + 1 ,如果有并列排名,输出为前一个的排名,但后一个排名的计算还是按照i + 1。

#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
class Country
{
public:
    int gold_medals;
    int total_medals;
    double per_gold;
    double per_total;
    int id;     //保存要输出的顺序
    int gold_medals_rank;
    int total_medals_rank;
    int per_gold_medals_rank;
    int per_total_medals_rank;
 
    Country(int g = 0, int t = 0, double p_g = 0, double p_m = 0,int ID = 0,
        int gmr = 0, int tmr = 0, int pgmr = 0,int ptmr = 0)
        :gold_medals(g),total_medals(t),per_gold(p_g),per_total(p_m),id(ID),gold_medals_rank(gmr),
        total_medals_rank(tmr),per_gold_medals_rank(pgmr),per_total_medals_rank(ptmr){}
};
 
bool cmp_gold(const Country &lhs, const Country &rhs)
{
    return lhs.gold_medals > rhs.gold_medals;
}
 
bool cmp_total(const Country &lhs, const Country &rhs)
{
    return lhs.total_medals > rhs.total_medals;
}
 
bool cmp_pgold(const Country &lhs, const Country &rhs)
{
    return lhs.per_gold > rhs.per_gold;
}
 
bool cmp_ptotal(const Country &lhs, const Country &rhs)
{
    return lhs.per_total > rhs.per_total;
}
 
bool cmp_id(const Country &lhs, const Country &rhs)
{
    return lhs.id < rhs.id;
}
 
void output_bestrank(int gold_rank, int total_rank, int p_gold_rank, int p_total_rank)  //输出
{
    int min1 = min(gold_rank,total_rank);
    int min2 = min(p_gold_rank,total_rank);
    int min_rank = min(min1,min2);
 
    if(gold_rank == min_rank)
        cout << gold_rank << ":" << 1 << endl;
    else if(total_rank == min_rank)
        cout << total_rank << ":" << 2 << endl;
    else if(p_gold_rank == min_rank)
        cout << p_gold_rank << ":" << 3 << endl;
    else
        cout << p_total_rank << ":" << 4 << endl;
}
 
int main()
{
    int N,M;
    vector<Country> all_country;
    vector<Country> cmp_country;
    vector<int> ID;      //保存要排序的国家顺序 按此顺序输出
    while(cin >> N >> M)
    {
        for(int i = 0; i < N; ++i)
        {
            int golds;
            int totals;
            double population;
            cin >> golds >> totals >> population;
            double per_golds = golds / population;
            double per_totals = totals / population;
            all_country.push_back(Country(golds,totals,per_golds,per_totals));
        }
 
        for(int i = 0; i < M; ++i)
        {
            int country_id;
            cin >> country_id;
            ID.push_back(country_id);
        }
 
        for(int i = 0; i != ID.size(); ++i)  //保存每个需要统计的国家的先后顺序
        {
            all_country[ID[i]].id = i;
            cmp_country.push_back(all_country[ID[i]]);
        }
 
        sort(cmp_country.begin(),cmp_country.end(),cmp_gold);  //根据金牌总数排序
        double prev = -1;
        for(int i = 0; i != cmp_country.size(); ++i)
        {
            if(cmp_country[i].gold_medals == prev)
                cmp_country[i].gold_medals_rank = cmp_country[i - 1].gold_medals_rank;
            else
            {
                prev = cmp_country[i].gold_medals;
                cmp_country[i].gold_medals_rank = i + 1;
            }
        }
 
        sort(cmp_country.begin(),cmp_country.end(),cmp_total);  //根据奖牌总数排序
        prev = -1;
        for(int i = 0; i != cmp_country.size(); ++i)
        {
            if(cmp_country[i].total_medals == prev)
                cmp_country[i].total_medals_rank = cmp_country[i - 1].total_medals_rank;
            else
            {
                prev = cmp_country[i].total_medals;
                cmp_country[i].total_medals_rank = i + 1;
            }
        }
     
        sort(cmp_country.begin(),cmp_country.end(),cmp_pgold);   //根据金牌人口比例排序 
        prev = -1;
        for(int i = 0; i != cmp_country.size(); ++i)
        {
            if(cmp_country[i].per_gold == prev)
                cmp_country[i].per_gold_medals_rank = cmp_country[i - 1].per_gold_medals_rank;
            else
            {
                prev = cmp_country[i].per_gold;
                cmp_country[i].per_gold_medals_rank = i + 1;
            }
        }
 
        sort(cmp_country.begin(),cmp_country.end(),cmp_ptotal);   //根据奖牌人口比例排序
        prev = -1;
        for(int i = 0; i != cmp_country.size(); ++i)
        {
            if(cmp_country[i].per_total == prev)
                cmp_country[i].per_total_medals_rank = cmp_country[i - 1].per_total_medals_rank;
            else
            {
                prev = cmp_country[i].per_total;
                cmp_country[i].per_total_medals_rank = i + 1;
            }
        }
 
        sort(cmp_country.begin(),cmp_country.end(),cmp_id);  //根据国家的先后顺序排序 即按此顺序输出
 
        for(int i = 0; i != cmp_country.size(); ++i)
        {
            output_bestrank(cmp_country[i].gold_medals_rank,cmp_country[i].total_medals_rank,
                            cmp_country[i].per_gold_medals_rank,cmp_country[i].per_total_medals_rank);
        }
 
        cout << endl;
 
        all_country.clear();
        cmp_country.clear();
        ID.clear();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值