浙江大学机试--奥运会排序

题目: 牛客网链接

概述: 给了每个国家的金牌数,奖牌数,人口数。然后给出四种排序条件,奖牌总数,金牌总数,金牌人口比例,奖牌人口比例。找出给定国家的最优排序方法。

思路: 用了两种方法来解决这个问题。一个是用一个二维数组,还有一个是面向对象的方法。 这一题数据集比较坑,有时候人口总数竟然会为0。

方法一:面向对象法

vector存储对象时候很巧妙 ,多复习。

#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

class Country
{
public:
   int gold;
   int medal;
   int plt;
   double perGold;
   double perMedal;
   int best;
   int method;
   Country(int gold, int medal, int plt)
   {
   	this -> gold = gold;
   	this -> medal = medal;
   	this -> plt = plt;
   	perGold = (double)gold / plt;
	if (gold == 0 && plt == 0)      //这里解释一下,因为测试用例有毛病,会有人口零,奖牌零的情况出现
    perGold = 0;            //而如果除数被除数都是0,那么结果是NAN——Not A Number
    perMedal = (double)medal / plt;      //而经过调试发现,调用sort的时候,sort会把vector以NAN为分界
    if (medal == 0 && plt == 0)
	perMedal = 0;      //分开来,然后各自进行排序,然后就出错了
   	best = 100000;
   	method = 100000;
   }
   
}; 

bool more(Country* c1, Country* c2, int flag)
{
	switch(flag)
	{
		case 1: return c1->gold > c2->gold; break;
		case 2: return c1->medal > c2->medal; break;
		case 3: return c1->perGold > c2->perGold; break;
		case 4: return c1->perMedal > c2->perMedal; break;
		drfault: break;
	}
	return false;
}

bool cmp1(Country* c1, Country* c2)
{
	return c1->gold > c2->gold; 
}
bool cmp2(Country* c1, Country* c2)
{
	return c1->medal > c2->medal;
}
bool cmp3(Country* c1, Country* c2)
{
	return c1->perGold > c2->perGold;
}
bool cmp4(Country* c1, Country* c2)
{
	return c1->perMedal > c2->perMedal; 
}


void selectSort(vector<Country*> staySort, int flag)
{
	int length = staySort.size();
	vector<Country*> temp;
	for(int i = 0; i < length; i++)
	{
		temp.push_back(staySort[i]);
	}
	switch(flag)
	{
		case 1: sort(temp.begin(), temp.end(), cmp1); break;
		case 2: sort(temp.begin(), temp.end(), cmp2); break;
		case 3: sort(temp.begin(), temp.end(), cmp3); break;
		case 4: sort(temp.begin(), temp.end(), cmp4); break;
		drfault: break;
	}

    int best = 1;
    if(temp[0]->best > best || (temp[0]->best == best && temp[0]->method > flag)){
        temp[0]->best = best;
        temp[0]->method = flag;
    }
    
    for(int i = 1; i < length; i++)
	{
       if(more(temp[i - 1], temp[i], flag))
	   {
        best = i + 1;
       }
       if(temp[i]->best > best || (temp[i]->best == best && temp[i]->method > flag))
	   {
         temp[i]->best = best;
         temp[i]->method = flag;
       }
    }
    
	

}

int main()
{
	int m, n;
	while(scanf("%d%d", &n, &m) != EOF)
	{
		vector<Country*> countries, staySort;
		for(int i = 0; i < n; i++)
		{
		int gold, medal, plt;
		scanf("%d%d%d", &gold, &medal, &plt);
		countries.push_back(new Country(gold, medal, plt));
	    }
	    for(int i = 0; i < m; i++)
		{
		int index;
		scanf("%d", &index);
        staySort.push_back(countries[index]);
        }

        selectSort(staySort, 1);
        selectSort(staySort, 2);
        selectSort(staySort, 3);
        selectSort(staySort, 4);
        for(int i = 0; i < m; i++)
		{
			printf("%d:%d\n", staySort[i] -> best, staySort[i] -> method);
		}
		printf("\n");
		
	}
	
	return 0;
}

方法二:二维数组法
二维数组的操作是个终点,我们采用iterator进行操作,在代码中划了重点。另外整体的思路也很重要。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

//用于sort函数 
bool cmp(double a, double b)
{
	return a > b;
}

//采用二维数组来进行存储,第一行是金牌总数,第二行是奖牌总数,第三行是金牌/人口,第四行是奖牌/人口 
int main()
{
	
	int n, m;
	
	while(scanf("%d%d", &n, &m) != EOF)
	{
		vector<vector<double> > country(4, vector<double>(n));
		for(int i = 0; i < n; i++)
		{
			int gold, medal, plt;
			double perGold, perMedal;
			scanf("%d%d%d", &gold, &medal, &plt);
			//因为数据集中给出的人口,有时候为0,所以考虑被除数为0的情况 

            perGold = (double)gold / plt;   
            if (gold == 0 && plt == 0)      //这里解释一下,因为测试用例有毛病,会有人口零,奖牌零的情况出现
            perGold = 0;            //而如果除数被除数都是0,那么结果是NAN——Not A Number
            perMedal = (double)medal / plt;      //而经过调试发现,调用sort的时候,sort会把vector以NAN为分界
            if (medal == 0 && plt == 0)      //分开来,然后各自进行排序,然后就出错了
            perMedal = 0;       
			country[0][i] = gold;
			country[1][i] = medal;
			country[2][i] = perGold;
			country[3][i] = perMedal;
		}
		//用来存储用来比较的m个 
		vector<vector<double> > ctryToCmp(4, vector<double>(m));
		for(int i = 0; i < m; i++)
		{
			//输入m个下标 
			int index;
			scanf("%d", &index);
			ctryToCmp[0][i] = country[0][index];
			ctryToCmp[1][i] = country[1][index];
			ctryToCmp[2][i] = country[2][index];
			ctryToCmp[3][i] = country[3][index];
		}
		//这里是二维数组操作的一个重点 
		for(vector<vector<double> > :: iterator it = country.begin(); it != country.end(); it++)
		{
			sort(it -> begin(), it -> end(), cmp);
		}
		
		//这里开始对这m个选出来要排序的数找他们的排名和最适合他们的排名方式 
		for(int i = 0; i < m; i++)
		{
			int best = n, method = 1;
			//分别对应着四中情况 
			for(int j = 0; j < 4; j++)
			{
				//与没排序前的m个一一对比,这样就可以按照顺序输出这m个国家的情况 。 
			    for(int k = 0; k < n; k++)
				{
					if(country[j][k] == ctryToCmp[j][i] && best > k + 1)
					{
						best = k + 1;
						method = j + 1;
						break;
					}					
				} 
				
				//如果是第一名就不用再进行比较了 
			    if(best == 1)
			    {
				    break;
				} 
			} 
			
			printf("%d:%d\n", best, method);
		} 
		 
		 printf("\n");
		
	}
	
	
	
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值