hdu3789——模拟题

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

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

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

Sample Input
  
  
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
 

Sample Output
  
  
1:3 1:1 2:1 1:2 1:1 1:1
 
做这种题,最考验耐心和精神状态了。比赛的时候没有写出来,因为自己静不下心来。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> 
#define N 1005
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
struct Node
{
	int seq;
	double num;
}gold[N],medal[N],g_rate[N],m_rate[N];

bool cmp(Node a,Node b)
{
	return a.num>b.num;
}
int ranking[N][5];
int n,m;
double a[N],b[N],c[N];
int d[N];
void compute(Node x[],int k)//第k种排序方式 
{
	sort(x,x+m,cmp);//进行排序,大的在前 
	ranking[x[0].seq][k]=1;
	int cnt=2;
	for(int i=1;i<m;i++)
	{
		if(x[i].num==x[i-1].num)//如果和前面的大小相等,则排名和前面一样 
		{
			ranking[x[i].seq][k]=ranking[x[i-1].seq][k];
			
		}
		else//否则就是第cnt个数 
			ranking[x[i].seq][k]=cnt;
		cnt++;
	}
}
int main(int argc, char *argv[]) {
	while(~scanf("%d%d",&n,&m))
	{
		for(int i=0;i<n;i++)
		{
			scanf("%lf%lf%lf",&a[i],&b[i],&c[i]);
		}
		for(int i=0;i<m;i++)
		{
			scanf("%d",&d[i]);
		}
		for(int i=0;i<m;i++)//选择出需要排序得那一部分 
		{
			gold[i].num=a[d[i]];
			gold[i].seq=d[i];
			medal[i].num=b[d[i]];
			medal[i].seq=d[i];
			g_rate[i].num=a[d[i]]/c[d[i]];
			g_rate[i].seq=d[i];
			m_rate[i].num=b[d[i]]/c[d[i]];
			m_rate[i].seq=d[i];
		}
		/*for(int i=0;i<m;i++)
		{
			printf("%lf,%lf,%lf,%lf\n",gold[i].num,medal[i].num,g_rate[i].num,m_rate[i].num);
		}*/
		memset(ranking,0,sizeof(ranking));
		compute(gold,1);//根据题目的意思,不同的排序方式 
		compute(medal,2);
		compute(g_rate,3);
		compute(m_rate,4);
		for(int i=0;i<m;i++)
		{
			int min=N,pos=1;
			for(int j=1;j<=4;j++)//找出四种排序方式中,排名最靠前的那种方式 
			{
				if(ranking[d[i]][j]<min)
				{
					min=ranking[d[i]][j];
					pos=j;
				}
			}
			printf("%d:%d\n",min,pos);
		}
		printf("\n");
	}
	return 0;
}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值