题目描述
小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); }