-
题目描述:
-
按要求,给国家进行排名。
-
输入:
-
有多组数据。
第一行给出国家数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
-
答疑:
解题遇到问题?分享解题心得?讨论本题请访问: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;
}