题目1007:奥运排序问题

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:9031

解决:1952

题目描述:

按要求,给国家进行排名。

输入:
有多组数据。
第一行给出国家数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

来源:
2010年浙江大学计算机及软件工程研究生机试真题
答疑:

解题遇到问题?分享解题心得?讨论本题请访问:http://t.jobdu.com/thread-7731-1-1.html

分析:之前看了半天题目都理解不了,大概是这么个意思:给出需要排序的国家,每个国家分别按照金牌总数 、 奖牌总数 、 金牌人口比例 、 奖牌人口比例四种排名。也即每个国家有四个排名结果,然后选取排名结果最高的排名,如果有并列的排名,则输出排名方式最小的排名。四种排名分别为1,2,3,4; 
注意:这里有一个很含糊的情况说明一下。就是给出需要排名的国家号不一定都是按照升序排列的,也就是说可以这样给3,1,2,0(需要排序的国家号)。这个问题因为没有考虑到导致提交一直通不过。 
我写的代码如下:

#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
struct pm //对所有国家的排名进行存储 
{
    int n;
    int way;
}temp[1000][4];
struct country
{
    int  n1;//金牌数 
    int  n2;//奖牌数 
    int  n3;//人口数 
    double n11;//金牌比例 
    double n22;//奖牌比例 
    int temp;//临时排名 
    int num; //国家编号 
}array[1000],b[1000];//b存的是参与排名的国家,num表示参与排名的给出的国家先后 
int cmp1(const country &a,const country &b)
{
    return a.n1>b.n1;
}
int cmp2(const country &a,const country &b)
{
    return a.n2>b.n2;
}
int cmp3(const country &a,const country &b)
{
    return a.n11>b.n11?1:0;
}
int cmp4(const country &a,const country &b)
{
    return a.n22>b.n22?1:0;
}
int cmp5(const pm &a,const pm &b)
{
    if(a.n!=b.n)
    return a.n<b.n;
    else return a.way<b.way;
}
int main()
{
    int c1,c2;
    while(cin>>c1>>c2)
    {
        for(int i=0;i<c1;i++)
        {
            cin>>array[i].n1>>array[i].n2>>array[i].n3;
            array[i].n11=(double)array[i].n1/array[i].n3;//求金牌比例 
            array[i].n22=(double)array[i].n2/array[i].n3;//求奖牌比例 
            array[i].num=i; 
        }
        for(int i=0;i<c2;i++)//求要进行排名的国家 
        {                   //特别注意给出排名的国家号并不一定是按照升序来的 
            int j;         //如,可能是2 0 1,而且输出是按照先2后0再1的
            cin>>j;
            b[i]=array[j];
            b[i].num=i;
        }
        sort(b,b+c2,cmp1);//对金牌排序   
        for(int i=0;i<c2;i++)
        for(int j=0;j<4;j++)
        temp[i][j].way=j+1;     
        b[0].temp=1;
        temp[b[0].num][0].n=1;
        for(int i=1;i<c2;i++)
        {
            if(b[i].n1==b[i-1].n1)
            {
                b[i].temp=b[i-1].temp;
                temp[b[i].num][0].n=b[i].temp;
            }else
            {
                b[i].temp=i+1;
                temp[b[i].num][0].n=b[i].temp;
            }       
        }
        sort(b,b+c2,cmp2);//对奖牌排序
        b[0].temp=1;
        temp[b[0].num][1].n=1;
        for(int i=1;i<c2;i++)
        {
            if(b[i].n2==b[i-1].n2)
            {
                b[i].temp=b[i-1].temp;
                temp[b[i].num][1].n=b[i].temp;
            }else
            {
                b[i].temp=i+1;
                temp[b[i].num][1].n=b[i].temp;
            }       
        }
        sort(b,b+c2,cmp3);//对金牌比例排序
        b[0].temp=1;
        temp[b[0].num][2].n=1;
        for(int i=1;i<c2;i++)
        {
            if(b[i].n11==b[i-1].n11)
            {
                b[i].temp=b[i-1].temp;
                temp[b[i].num][2].n=b[i].temp;
            }else
            {
                b[i].temp=i+1;
                temp[b[i].num][2].n=b[i].temp;
            }   
        }
        sort(b,b+c2,cmp4);//对奖牌比例排序
        b[0].temp=1;
        temp[b[0].num][3].n=1;
        for(int i=1;i<c2;i++)
        {
            if(b[i].n22==b[i-1].n22)
            {
                b[i].temp=b[i-1].temp;
                temp[b[i].num][3].n=b[i].temp;
            }else
            {
                b[i].temp=i+1;
                temp[b[i].num][3].n=b[i].temp;
            }   
        }
        for(int i=0;i<c2;i++)
        sort(temp[i],temp[i]+4,cmp5);   
        for(int i=0;i<c2;i++)//输出第一个即可
        cout<<temp[i][0].n<<":"<<temp[i][0].way<<endl;
        cout<<endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1007
    User: 陆义杰
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1632 kb
第二个思路是借鉴别人的,排序也是纯粹的自己写的,感觉逻辑挺好,就拿过来比对一下。

/*********************************  
*   日期:2013-3-3 
*   作者:SJF0115  
*   题号: 九度OJ 题目1007:奥运排序问题 
*   来源:http://ac.jobdu.com/problem.php?pid=1007 
*   结果:AC  
*   来源:2011年浙江大学计算机及软件工程研究生机试真题 
*   总结:  
**********************************/   
#include<stdio.h>  
#include<stdlib.h>  
#include<limits.h>  

//结构体  
typedef struct Country{  
    int GoldNum;//金牌数  
    int MedalNum;//奖牌数  
    int PeopleNum;//人口数  
    double GoldRatio;//金牌比例  
    double MedalRatio;//奖牌比例  
    int SKind;//最佳排名类型  
    int BestRank;//最佳排名  
    int Rank;//当前排名  
}Country;  

Country country[1000];  

int main () {  
    int N,M,i,j,ID;   
    Country countrySort[1001];  
    while(scanf("%d %d",&N,&M) != EOF){   
        //给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。  
        for(i = 0;i < N;i++){  
            scanf("%d %d %d",&country[i].GoldNum,&country[i].MedalNum,&country[i].PeopleNum);  
            country[i].GoldRatio = country[i].GoldNum * 1.0 / country[i].PeopleNum;  
            country[i].MedalRatio = country[i].MedalNum * 1.0 / country[i].PeopleNum;  
        }  
        //给出要排序的M个国家号。  
        for(i = 0;i < M;i++){      
            scanf("%d",&ID);  
            countrySort[i] = country[ID];  
        }  
        for(i = 0;i < M;i++){  
            //金牌数排序  
            countrySort[i].Rank = 1;  
            for(j = 0;j < M;j++){  
                if(countrySort[i].GoldNum < countrySort[j].GoldNum){  
                    countrySort[i].Rank++;  
                }  
            }  
            countrySort[i].BestRank = countrySort[i].Rank;  
            //printf("J:%d\n",countrySort[i].BestRank);  
            countrySort[i].SKind = 1;  
            //奖牌数排序  
            countrySort[i].Rank = 1;  
            for(j = 0;j < N;j++){  
                if(countrySort[i].MedalNum < countrySort[j].MedalNum){  
                    countrySort[i].Rank++;  
                }  
            }  
            if(countrySort[i].Rank < countrySort[i].BestRank){  
                countrySort[i].BestRank = countrySort[i].Rank;  
                countrySort[i].SKind = 2;  
            }  
            //printf("J2:%d\n",countrySort[i].Rank);  
            //金牌人口比例排序  
            countrySort[i].Rank = 1;  
            for(j = 0;j < N;j++){  
                if(countrySort[i].GoldRatio < countrySort[j].GoldRatio){  
                    countrySort[i].Rank++;  
                }  
            }  
            if(countrySort[i].Rank < countrySort[i].BestRank){  
                countrySort[i].BestRank = countrySort[i].Rank;  
                countrySort[i].SKind = 3;  
            }  
            //printf("J3:%d\n",countrySort[i].Rank);  
            //奖牌人口比例排序  
            countrySort[i].Rank = 1;  
            for(j = 0;j < N;j++){  
                if(countrySort[i].MedalRatio < countrySort[j].MedalRatio){  
                    countrySort[i].Rank++;  
                }  
            }  
            if(countrySort[i].Rank < countrySort[i].BestRank){  
                countrySort[i].BestRank = countrySort[i].Rank;  
                countrySort[i].SKind = 4;  
            }  
            //printf("J4:%d\n",countrySort[i].Rank);  
            //输出  
            printf("%d:%d\n",countrySort[i].BestRank,countrySort[i].SKind);  
        }  
        //每组数据后加一个空行。  
        printf("\n");  
    }//while  
    return 0;  
}
下面这个是我们班何大神写的,代码量果然降低了不少。

#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
struct country
{
    int gold;
    int sum;
    int people;
    int index;
}a[10000],b[10000];
bool cmp1(country a,country b){
    return a.gold>b.gold;
}
bool cmp2(country a,country b){
    return a.sum>b.sum;
}
bool cmp3(country a,country b){
    return (a.gold*b.people)>(b.gold*a.people);
}
bool cmp4(country a,country b){
    return (a.sum*b.people)>(b.sum*a.people);
}
int rank[10000][4];
int n,m;
int main(){ 
    while (cin>>n>>m){
        for (int i=0;i<n;i++){
            cin>>a[i].gold>>a[i].sum>>a[i].people;
        }
        for (int i=0;i<m;i++){
            int r;
            cin>>r;
            b[i]=a[r];
            b[i].index=i;
        }
        sort(b,b+m,cmp1);
        rank[b[0].index][0]=1;
        for (int i=1;i<m;i++){
            if (!cmp1(b[i],b[i-1]) && !cmp1(b[i-1],b[i])) rank[b[i].index][0] = rank[b[i-1].index][0];
            else rank[b[i].index][0] = i+1;
        }
        sort(b,b+m,cmp2);
        rank[b[0].index][1]=1;
        for (int i=1;i<m;i++){
            if (!cmp2(b[i],b[i-1]) && !cmp2(b[i-1],b[i])) rank[b[i].index][1] = rank[b[i-1].index][1];
            else rank[b[i].index][1] = i+1;
        }
        sort(b,b+m,cmp3);
        rank[b[0].index][2]=1;
        for (int i=1;i<m;i++){
            if (!cmp3(b[i],b[i-1]) && !cmp3(b[i-1],b[i])) rank[b[i].index][2] = rank[b[i-1].index][2];
            else rank[b[i].index][2] = i+1;
        }
        sort(b,b+m,cmp4);
        rank[b[0].index][3]=1;
        for (int i=1;i<m;i++){
            if (!cmp4(b[i],b[i-1]) && !cmp4(b[i-1],b[i])) rank[b[i].index][3] = rank[b[i-1].index][3];
            else rank[b[i].index][3] = i+1;
        }
        for (int i=0;i<m;i++){
            int r=rank[i][0];
            int index=1;
            for (int j=1;j<4;j++){
                if (rank[i][j]<r){
                    r=rank[i][j];
                    index=j+1;
                }
            }
            cout<<r<<":"<<index<<endl;
        }
        cout<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值