题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=6666
题意:
一般CCPC金牌获奖比例为前10%,但是总有意外发生,如假设115只队伍参赛,那么10%为11.5只队伍金牌,那么如果四舍五入到12,第12名就会获得金牌,如果舍去变成11,那么第12名就为银牌。
现在给你参赛队伍的数量n,以及金牌获奖比例10d%中的d,让你求出其中可能获得金牌也可能获得银牌的队伍名称,如果没有则输出Quailty is very great
思路:
题目开头就说了这一题是本场比赛的签到题,哈哈哈很开心能签到成功。
首先我们用一个结构体来存队伍的名称,AC的数量和惩罚时间,利用sort函数,自己写一个cmp比较规则,先比AC的数量,然后再比惩罚时间,也就是做出一个类似榜单的东西。
struct Team
{
char name[15];//队名
int num;//解决问题
int time;//罚时
}team[maxn];
bool cmp(Team p1,Team p2)
{
if(p1.num>p2.num)//一级排序
{
return true;
}
else if(p1.num==p2.num)
{
if(p1.time<p2.time)//二级排序
{
return true;
}
else
{
return false;
}
}
return false;
}
然后我们根据n和d计算出实际应该多少只队伍获得金牌,得出的结果检查一下小数部分是不是0.5,如果不是0.5,那么直接输出Quailty is very great即可,如果有0.5,那么将这个数向上取整,然后输出排名为这个数的队伍名称即可。
这题有个坑!!!非常小但是很深的坑!!!
在保存获奖队伍数量的时候,不能用double!!!
只能用float!!!
别问我怎么知道的,一次次的WA,发现出来的
别问我为什么,我也不知道
用double错误的截图:
用float正确的截图:
最后附上参考代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 100011
using namespace std;
struct Team
{//队伍的结构体
char name[15];//队名
int num;//解决问题
int time;//罚时
}team[maxn];
bool cmp(Team p1,Team p2)
{//sort的比较函数
if(p1.num>p2.num)//一级排序
{//先比AC数量
return true;
}
else if(p1.num==p2.num)
{
if(p1.time<p2.time)//二级排序
{//再比惩罚时间
return true;
}
else
{
return false;
}
}
return false;
}
int main()
{
int t,n,d;
double ans;//计算实际排名
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&d);
for(int i=1;i<=n;i++)
{//读取信息
scanf("%s%d%d",team[i].name,&team[i].num,&team[i].time);
}
sort(team+1,team+1+n,cmp);//从1开始排序,排序成从大到小
ans=0.1*d*n;//计算实际金牌获奖队伍
int t=ans;//获取整数位
if(ans-t!=0.5)
{//如果小数部分不是0.5
printf("Quailty is very great\n");
}
else
{//输出该队队名
printf("%s\n",team[t+1].name);
}
}
return 0;
}