网易1:奖学金

小v今年有n门课,每门都有考试,为了拿到奖学金,小v必须让自己的平均成绩至少为avg。每门课由平时成绩和考试成绩组成,满分为r。现在他知道每门课的平时成绩为ai ,若想让这门课的考试成绩多拿一分的话,小v要花bi 的时间复习,不复习的话当然就是0分。同时我们显然可以发现复习得再多也不会拿到超过满分的分数。为了拿到奖学金,小v至少要花多少时间复习。

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

struct score
{
    int ai;//平时分
    int bi;//考试得到一份需付出的努力
};

//以下两种重载<的方法选择其一即可,注意这里不能写<=只能写<或>
bool cmp(score &s1, score &s2)
{
    return s1.bi < s2.bi;
}

bool operator<(const score& s1, const score& s2)
{
    return s1.bi < s2.bi;
}

void print_vector(vector<score>& ab)
{
    for (int i = 0; i < ab.size(); i++)
    {
        cout << ab[i].ai << "  " << ab[i].bi << endl;
    }
}

/*
贪心算法:
首先将(ai,bi)以bi从小到大排序,然后先取小的bi贡献多余的精力来换取成绩,一直到最后满足成绩即可。
*/
int main()
{
    int n, r,avg;
    /*一定要注意这里:因为它的测试用例是连续输入的,所以必须使整个过程在while循环里.
    还有就是注意求和的数定义为long或者long long,否则会越界
    */
    while(cin>>n>>r>>avg)
    {
        int i = 0;
        long int sumScore = 0;//总的平时分
        vector<score> ab(n);
        while (i < n)
        {
            cin >> ab[i].ai >> ab[i].bi;
            sumScore += ab[i].ai;
            i++;
        }
        //print_vector(ab);
        //以付出努力大小由小到大排序
        sort(ab.begin(), ab.end(),cmp);
        //print_vector(ab);
        //当考试成绩小于需要的成绩时,继续循环
        long int timeScore = 0, needScore = avg * n - sumScore, spendTime = 0;
        i = 0;
        while (timeScore < needScore && i < n)
        {
            //若将平时分补齐到10后仍然还不够,则继续努力干,加分
            timeScore += r - ab[i].ai;
            if (timeScore < needScore)
            {
                spendTime += (r - ab[i].ai) * ab[i].bi;
                i++;
            }
            else
            {
                timeScore -= r - ab[i].ai;
                spendTime += (needScore - timeScore) * ab[i].bi;
                break;
            }
        }
        cout << spendTime << endl;
    }
    return 0;
}
全部评论

相关推荐

10-05 23:02
东北大学 Java
我说句实话啊:那时候看三个月培训班视频,随便做个项目背点八股,都能说3 40w是侮辱价
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务