奥运排序问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2331 Accepted Submission(s): 510
Problem Description
按要求,给国家进行排名。
Input
有多组数据。
第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。
第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。
接下来一行给出M个国家号。
第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。
第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。
接下来一行给出M个国家号。
Output
排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例
对每个国家给出最佳排名排名方式 和 最终排名
格式为: 排名:排名方式
如果有相同的最终排名,则输出排名方式最小的那种排名,对于排名方式,金牌总数 < 奖牌总数 < 金牌人口比例 < 奖牌人口比例
如果有并列排名的情况,即如果出现金牌总数为 100,90,90,80.则排名为1,2,2,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
Source
Recommend
notonlysuccess
开始把题意理解错了。做出了自己理解错了的一道题。题目只要求排给出的m个国家的排名而不是全部国家的排名。还有要注意按输入顺序输出m个国家的最佳排名。
不想用库函数。自己写的改版的二叉排序树。
#include <stdio.h>
typedef struct
{
double data;
int left,right,down;
} team;
team sort1[5000],sort2[5000],sort3[5000],sort4[5000];//建四个二叉排序树
int q,w,e,r,rk;//用q,w,e,r来分配数组。记录下个可用的结构数组空间
int ranks[5000][4];//存入每个国家的四种排名
typedef struct
{
int sg,sp;
double pp;
} ct;
void btree(int *root,int *c,team *sorts,double data)//根据data的值来排序
{
int now;//记录当前位置
if(*root==-1)
{
*root=*c;//分配空间
sorts[*root].data=data;
sorts[*root].down=sorts[*root].left=sorts[*root].right=-1;
(*c)++;//指向下个可用空间
}
else
{
now=*root;
if(data<sorts[now].data)
btree(&sorts[now].left,c,sorts,data);
else if(data>sorts[now].data)
btree(&sorts[now].right,c,sorts,data);
else
btree(&sorts[now].down,c,sorts,data);//如果相等就往下沉
}
}
void saverank(int root,team *sorts,int way,int pa)//记录排名。way为排序方式
{//pa 为父亲的地址
if(root==-1)
return;//判断是否为空
saverank(sorts[root].right,sorts,way,root);//先记录data较大国家排名
if(pa!=-1&&sorts[root].data==sorts[pa].data)//如果data和父亲相等则
//排名也相同。但rk还是要加。
ranks[root][way]=ranks[pa][way],rk++;
else
ranks[root][way]=++rk;//不相等排名直接后挪
saverank(sorts[root].down,sorts,way,root);//记录当前点一下。即data相等点排名
saverank(sorts[root].left,sorts,way,root);//记录data较小的国家排名
}
int main()
{
ct city[5000];
int i,j,n,m,sg,sp,num[5000],ans;//sg金牌数,sp奖牌数,num记录要排名的国家
double pp;//记录人口数
int root1,root2,root3,root4;//四个排序二叉树的根
while(scanf("%d%d",&n,&m)!=EOF)
{
q=w=e=r=0;
root1=root2=root3=root4=-1;//初始化
for(i=0;i<n;i++)
{
scanf("%d%d%lf",&sg,&sp,&pp);//读入数据用四种方式排序
city[i].sg=sg;
city[i].sp=sp;
city[i].pp=pp;
}
for(i=0;i<m;i++)
scanf("%d",&num[i]);//存入需排序国家号
for(i=0;i<m;i++)
{
btree(&root1,&q,sort1,(double)city[num[i]].sg);
btree(&root2,&w,sort2,(double)city[num[i]].sp);
btree(&root3,&e,sort3,city[num[i]].sg/city[num[i]].pp);
btree(&root4,&r,sort4,city[num[i]].sp/city[num[i]].pp);
}
saverank(root1,sort1,0,-1),rk=0;//记录四种排序中国家的排名
saverank(root2,sort2,1,-1),rk=0;
saverank(root3,sort3,2,-1),rk=0;
saverank(root4,sort4,3,-1),rk=0;
for(i=0;i<m;i++)
{
ans=0;
for(j=0;j<4;j++)//找出最佳排序名次和方式
{
if(ranks[i][j]<ranks[i][ans])
ans=j;
}
printf("%d:%d\n",ranks[i][ans],ans+1);
}
printf("\n");
}
return 0;
}
/*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
*///hdu 3789
一同学的思想感觉很经典于是给他代码实现了。没有了繁琐的排序。给排位问题提供了新的思路。
不过要用g++提交才行c++就是错的。不知道为什么。可能对浮点数处理不一样吧。
#include <stdio.h>
struct country
{
double value[4];//分别代表金牌数。奖牌数。金牌人口比列。奖牌人口比列
int rk[4];//分别代表四种排名方式
} ct[10000];//代表国家
int wrk[10000];
int main()
{
int n,m,i,j,k,a,b,ans;
double p;
while(~scanf("%d%d",&n,&m))
{
for(i=0; i<n; i++)
{
scanf("%lf%lf%lf",&ct[i].value[0],&ct[i].value[1],&p);
ct[i].value[2]=ct[i].value[0]/p;//金牌人均总数
ct[i].value[3]=ct[i].value[1]/p;//奖牌人均总数
ct[i].rk[0]=ct[i].rk[1]=ct[i].rk[2]=ct[i].rk[3]=1;//初始排名都为1
}
for(i=0; i<m; i++)//记录待排名的国家号
scanf("%d",&wrk[i]);
for(i=0;i<m;i++)//利用排名原理。感觉很经典。排名数就是比你优秀的人数加1(优秀标准由题目给出)
{
a=wrk[i];
for(j=0;j<m;j++)
{
b=wrk[j];
for(k=0;k<4;k++)
{
if(ct[a].value[k]<ct[b].value[k])
ct[a].rk[k]++;
}
}
}
for(i=0; i<m; i++)
{
ans=0;
a=wrk[i];
for(j=0; j<4; j++)//记录最佳排名方式
if(ct[a].rk[j]<ct[a].rk[ans])
ans=j;
printf("%d:%d\n",ct[a].rk[ans],ans+1);
}
printf("\n");
}
return 0;
}