❄️ | 题目描述
给出n个标准,以及对应的n个结果。结果为1代表通过考试,结果为0代表不通过考试
要求在n个标准中选出一个作为阈值。使得预测准确的数量达到最大
预测准确是:当标准 < 阈值,结果为0;当标准 > 阈值,结果为1
如果有预测准确的数量一样的阈值,选择最大的。
✨ | 实现思路
首先应该将n组数据排序
加入选择3作为阈值,那么预测准确的次数就是:
3右边(包括3)结果为1的数 + 3左边(不包括3)结果为0的数【这里可以用前缀和快速统计】
从大到小枚举,最后选择出答案。
当然枚举是需要注意:有可能枚举的标准是相等的,那么一定要将指针移动到最左边【第一个大于下一个不同标准的位置】。因为预测的能通过的标准是 ≥ Yi
当然也可以通过二分查找确定下标位置
💓 | 具体代码
-
二分
#include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef pair<int, int> PII; #define x first #define y second const int N = 100010; int n; int a[N]; PII res[N]; int cnt[N]; int main() { cin >> n; for (int i = 1; i <= n; i ++) { int y, w; cin >> y >> w; res[i] = {y, w}; a[i] = y; } sort(res + 1, res + 1 + n); sort(a + 1, a + 1 + n); for (int i = 1; i <= n; i ++) cnt[i] = res[i].y + cnt[i - 1]; int ans = 0, mmax = -1; // 求最大值时注意初始化 for (int i = n; i >= 1; i --) { int pos = lower_bound(a + 1, a + 1 + n, a[i]) - a - 1; // 找到小于当前阈值的第一个(最大的)数 // cout << pos << ' '; int num = cnt[n] - cnt[pos] + pos - cnt[pos]; // 预测正确的个数 if (num > mmax) { mmax = num; ans = a[i]; } } cout << ans << endl; }
-
继续循环判断条件
#include <iostream> #include <algorithm> using namespace std; typedef pair<int, int> PII; #define x first #define y second const int N = 100010; int n; int s[N]; PII w[N]; int main() { cin >> n; for (int i = 1; i <= n; i ++) { int a, res; cin >> a >> res; w[i] = {a, res}; } w[0] = {-1, 0}; sort (w + 1, w + 1 + n); s[n + 1] = 0; for (int i = n; i >= 0; i --) { s[i] = s[i + 1] + w[i].y; } /* s[i]: y >= yi时,成绩是1的数量 */ int ans = 0; int num = 0; for (int i = n; i >= 0; i --) { if (w[i].x == w[i - 1].x) continue; // 这里可以用二分找到大于 w[i].x 的最小的数 if (s[i] + i - (s[1] - s[i]) > num) // 预测成功的数量 = 1~i-1中为0的数量 + i~n中为1的数量 { num = s[i] + i - (s[1] - s[i]); ans = w[i].x; } } cout << ans << endl; }