【C】奥运排序问题

题目描述

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

输入描述:

有多组数据。
第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。
第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。
接下来一行给出M个国家号。

输出描述:

排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例 
对每个国家给出最佳排名排名方式 和 最终排名
格式为: 排名:排名方式
如果有相同的最终排名,则输出排名方式最小的那种排名,对于排名方式,金牌总数 < 奖牌总数 < 金牌人口比例 < 奖牌人口比例 
如果有并列排名的情况,即如果出现金牌总数为 100,90,90,80.则排名为1,2,2,4.
每组数据后加一个空行。
示例1

输入

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

#include<stdio.h>
#include<algorithm>
using namespace std;
struct COUNTRY{
	double gold;//金牌数
	double medal;//奖牌数
	double porp;//人口
    int no;//国家号
    double gp;//金牌:人口
    double mp;//奖牌:人口
	int no1;//按方式1:金牌总数名次
    int no2;//按方式2:奖牌总数名次
	int no3;//按方式3:金牌:人口名次
    int no4;//按方式4:奖牌:人口名次
	int type;//排名方式
	int best;//最佳排名
}buf[100];
int main(){
	int n,m,i,j;
	int num[100];
	while(scanf("%d%d",&n,&m)!=EOF){
    
	for(i=0;i<n;i++){
		scanf("%d %d %d",&buf[i].gold,&buf[i].medal,&buf[i].porp);
		buf[i].no=i;
	}
	for(i=0;i<m;i++){
		scanf("%d",&num[i]);
	}
	COUNTRY buff[100];//需要参与排名的国家
	for(i=0;i<n;i++){
		for(j=0;j<m;j++){
			if(buf[i].no==num[j]){
				buff[j]=buf[i];//相同结构体可以直接复制
			}
		}
	}
	for(j=0;j<m;j++){
		if(buff[j].porp==0){//避免除0错误:-1.#IND00或1.#IND00
			if(buff[j].gold==0&&buff[j].medal!=0){
				buff[j].gp=-32767;//金牌=0,奖牌!=0,用方式四,设buff[j].gp为最小
				buff[j].mp=32767;//buff[j].mp也为最大
			}
			else{
				buff[j].gp=32767;
                buff[j].mp=32767;
			}
		}
		else{
			buff[j].gp=buff[j].gold/buff[j].porp;
		    buff[j].mp=buff[j].medal/buff[j].porp;
		}
		buff[j].no1=1;buff[j].no2=1;buff[j].no3=1;buff[j].no4=1;
	}
	for(j=0;j<m;j++){
		for(i=0;i<m;i++){
			if(buff[i].gold>buff[j].gold) buff[j].no1++;
			if(buff[i].medal>buff[j].medal) buff[j].no2++;
			if(buff[i].gp>buff[j].gp) buff[j].no3++;
			if(buff[i].mp>buff[j].mp) buff[j].no4++;
		}
	}
	for(j=0;j<m;j++){
		if(buff[j].no1<=buff[j].no2&&buff[j].no1<=buff[j].no3&&
			buff[j].no1<=buff[j].no4){
				buff[j].type=1;
				buff[j].best=buff[j].no1;
		}
		else if(buff[j].no2<buff[j].no1&&buff[j].no2<=buff[j].no3&&
			buff[j].no2<=buff[j].no4){
				buff[j].type=2;
				buff[j].best=buff[j].no2;
		}
		else if(buff[j].no3<buff[j].no1&&buff[j].no3<buff[j].no2&&
			buff[j].no3<=buff[j].no4){
				buff[j].type=3;
				buff[j].best=buff[j].no3;
		}
		else{
			buff[j].type=4;
			buff[j].best=buff[j].no4;
		}
	}
	for(j=0;j<m;j++){
		printf("%d:%d\n",buff[j].best,buff[j].type);
	}
    printf("\n");
	}
	return 0;
}

注:(1)int整数除以int整数一定得到的是int整数,用double表示的一个整数除以用int表示的一个整数得到的才可能是小数,或者是,用int表示的一个整数除以用double表示的一个整数得到的才可能是小数,或者是用double表示的一个整数除以用double表示的一个整数得到的才可能是小数。

(2)由于人口以百万计,测试用例中会出现人口数为0的情况,需要考虑当人口为零时,避免除零错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值