热身赛T3(奖学金评定)

Problem Description

zpy 学习非常努力,想要评奖学金,而奖学金评定的一大标准就是绩点(GPA)高低。

单个科目的 GPA 的计算公式如下:f(x)=min(5.0,(x−45)×0.1) ,其中 x 表示课程成绩,众所周知当 x<60 时 f(x)=0 。

在评定奖学金时用的是平均学分绩点,简而言之就是以学分为权重的绩点。

假设你考了三门课,绩点分别为 3.5,4.1,4.2 ,学分分别为 3,5,1 ,那么最终的平均学分绩点为 (3.5×3+4.1×5+4.2×1)/(3+5+1)=3.91 。

同时,在 HDU 存在两种竞赛类加分政策,第一种是学科类竞赛加分,第二种是体育与艺术类竞赛加分。

对于第一类加分,会直接在你的平均学分绩点中加上奖励绩点;假设加分前你的 GPA 为 3.48 ,奖励了 1.8 的绩点,那么你的最终平均学分绩点为 5.28 (虽然学院文件中说的最高绩点是 5.0 封顶,但是实际评奖学金的时候是可以超过 5.0 的)。

第二类加分制度奖励的不是绩点,而是学分额度。具体来说,你可以选择学分总和小于等于学分额度的若干门课程,将这些课程的成绩通过如下公式更改。

HDU 存在新旧两种公式(分别是改革前和改革后),第一个是 g(x)=√x ×10 ,第二个是 t(x)=(x−70)×10/34+70 。不难发现第二个公式其实是根据第一个改良而来的(两个公式都可以让你考 36 分就及格,但是第二个公式在大于 70 分时反而会使分数变少,所以 zpy 不会在成绩大于等于 70 时使用第二个公式)。

依然假设你考了三门课,成绩分别为 81,49,36 ,学分分别为 3,5,1 ,奖励的学分额度为 5 分。
你可以选择 1 分和 3 分的两门课,也可以只选择 5 分的那门课。为了方便起见,zpy 会优先选择成绩最低的课程,如果有多门课程成绩一样,他会优先选择学分最少的课程。

如果以第一种公式计算,他最终的成绩为 90,49,60 ,如果使用第二种,他的最终成绩为 81,49,60 。
已知 zpy 所有课程的成绩以及学分、他的第一类加分的奖励绩点、他的第二类加分的学分额度,以及全年级其他同学的最终平均学分绩点。他想知道自己在改革前和改革后(也即使用第一种公式和第二种公式时)的年级排名。

上文提到的所有公式的输入与输出都不一定是整数!
友情提醒:在c++中,开根运算可以用 sqrt() 这个函数实现。

Input

第一行一个整数 T(1≤T≤100) ,表示测试数据组数。接下来包含 T 组测试数据。

对于每组测试数据,第一行输入两个整数 n,d(1≤n≤50,0≤d≤24) 和一个实数 c(0≤c≤1.8),表示 zpy 参加考试的课程数量、第二类加分的学分额度和第一类加分的奖励绩点。

接下来输入 n 行,每行两个整数 x,y(0≤x≤100,1≤y≤5) ,表示每门课程的成绩和学分。

接下来一行输入一个整数 k(1≤k≤100) ,表示全年级除了 zpy 外还有多少同学。

最后一行输入 k 个实数 ti(0≤ai≤5.0),表示每个人的最终平均学分绩点。

Output

对于每组测试数据,输出两个数表示改革前和改革后 zpy 的年级排名。

数据保证不会有人的绩点和 zpy 一样。

Sample Input

1
3 5 1.0
81 3
49 5
36 1
4
5.0 1.0 2.5 1.5

Sample Output

2 3

这道题的题目很长,给人的感觉很难,但是只要耐心的将题读完并且理解题意,就会发现这道题非常简单。
计算量很大,对代码细节要求比较高。

#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
struct stu
{
    double cj,xf,cj1,cj2;
    double jd,jd1;
}ss[55];
bool cmp(stu a,stu b)
{
    if(a.cj==b.cj)
    {
        return a.xf<b.xf;
    }
    else
    {
        return a.cj<b.cj;
    }
}
double gs1(int a)//公式1函数,根号中应该为整形
{
    double res;
    res=sqrt(a)*10;
    return res;
}
double gs2(double a)//公式2函数
{
    double res;
    res=(a-70)*10/34+70;
    return res;
}
double jdhs(double a)//绩点函数  众所周知,当 x<60 时 f(x)=0
{
    double res;
    if(a>=60)
    {
        res=(a-45)*0.1;
    }
    else
    {
        res=0;
    }
    return res;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,d;
        double zxf=0,jdz1=0,jdz2=0;
        double c;
        cin>>n>>d>>c;
        for(int a=0;a<n;a++)
        {
            cin>>ss[a].cj>>ss[a].xf;
            zxf+=ss[a].xf;
        }
        sort(ss,ss+n,cmp);
        for(int a=0;a<n;a++)              //对公式1进行求解
        {
            int pd=0;                     //为了方便起见,zpy 会优先选择成绩最低的课程,如果有多门课程成绩一样,他会优先选择学分最少的课程。
            if(pd+=ss[a].xf<d)
            {
                ss[a].cj1=gs1(ss[a].cj);
            }
            ss[a].jd1=jdhs(ss[a].cj1);
            jdz1+=ss[a].jd1*ss[a].xf;
        }
        for(int a=0;a<n;a++)           //对公式2进行求解
        {
            int pd=0;                  //为了方便起见,zpy 会优先选择成绩最低的课程,如果有多门课程成绩一样,他会优先选择学分最少的课程。
            if(pd+=ss[a].xf<d)
            {
                ss[a].cj2=gs2(ss[a].cj);
            }
            ss[a].jd=jdhs(ss[a].cj2);
            jdz2+=ss[a].jd*ss[a].xf;
        }
        double pjfjd1=(jdz1/zxf)+c;
        double pjfjd2=(jdz2/zxf)+c;
        //cout<<pjfjd<<" "<<pjfjd1<<endl; //测试数值代码
        int xs;
        cin>>xs;              //输入比较学生人数
        double arr;
        int pdd=xs+1;         //加上zpy本人,不排除成为第5的可能
        int pddd=xs+1;        //加上zpy本人,不排除成为第5的可能
        for(int a=0;a<xs;a++) //进行比较
        {
            cin>>arr;
            if(pjfjd1>arr)
            {
                pddd--;
            }
            if(pjfjd2>arr)
            {
                pdd--;
            }
        }
        cout<<pddd<<" "<<pdd<<endl;
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焚冉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值