题目描述
小A去参加W大学的一个招生项目.
除了小A,还有n个人报名了W大学的这个招生项目,而W大学只招收m个人.
每个人有一个高考分和一个校测分,分数都是非负整数,满分都是p,分数都不大于p.
因为小A优异的竞赛成绩,W大学给了小A承诺,他将会校测给满分.
然后每个人的最终得分为 高考分85% + 校测分15%.
最终得分从高到低排前m高的将被录取,如果有同分,小A将优先被录取.
求小A高考至少要考到多少分才能被W大学录取.
题目分析
这个题目是有点恶心的,当时wa了五六发才过,存在的特殊样例是我没到的,其实用这个题目的正解是二分,用二分去做的话就不用考虑特殊情况,当时看着签到题只有百分之十的通过率,我一度怀疑题目有问题,但是想想还是有那么多人过,当然得从自己身上去找原因。坑点就在于减去校测分之后可能会小于等于0,那么小A就不用考试,直接0分,因为分数不可能为负数,因为这个点,wa了无数发~~
方法一:简单模拟
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
struct node
{
int a, b;
double c;
bool operator<(const node x) const
{
return c > x.c;
}
} w[maxn];
int main()
{
int n, m, p;
scanf("%d%d%d", &n, &m, &p);
for (int i = 1; i <= n; ++i)
scanf("%d%d", &w[i].a, &w[i].b), w[i].c = w[i].a * 1.0 * 0.85 + w[i].b * 1.0 * 0.15;
sort(w + 1, w + n + 1);
double ans = w[m].c;
ans -= p * 0.15;
if (ans <= 0)
{
puts("0");
return 0;
}
ans = ans / 0.85;
// cout <<(int) ans << ' ' << ans << endl;
if ((int)ans != ans)
cout << (int)ans + 1 << "\n";
else
cout << (int)ans << "\n";
}方法二:二分
因为题目要去找一个数,这个数能够让小A被录取,这样自然而然的想到用二分查找的方法,这样能快速查找一个数,并且避免特殊情况的干扰,注意一点就是相乘之后会大于int类型的范围,所以用long long去定义。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <set>
#include <map>
#include <math.h>
#include <vector>
#include <queue>
#include <string.h>
typedef long long ll;
using namespace std;
#define pi acos(-1.0)
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
struct node
{
ll a, b, c;
bool operator<(const node x) const
{
return c > x.c;
}
} w[maxn];
int main()
{
ll n, m, p;
scanf("%lld%lld%lld", &n, &m, &p);
for (int i = 1; i <= n; ++i)
{
scanf("%lld%lld", &w[i].a, &w[i].b);
w[i].c = w[i].a * 85 + w[i].b * 15;
}
sort(w + 1, w + n + 1);
ll l = 0, r = p, ans;
ll ss = w[m].c;
while (l <= r)
{
ll mid = l + r >> 1;
if (mid * 85 + p * 15 >= ss)
{
r = mid - 1;
ans = mid;
}
else
l = mid + 1;
}
printf("%lld\n", ans);
}
京公网安备 11010502036488号