小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;
}
京公网安备 11010502036488号