期末预测之最佳阈值
题目
n个学生,每个学生有一个阈值和一个结果,结果有0,1两种选择,现在可选择阈值进行判断大于阈值取1,小于取0,问预测结果正确的次数最多的阈值是谁,如果预测次数相同,输出最大的阈值。
思路
- 结果和数据输入无关可排序,且如果有序,那么显然该阈值左侧预测结果为0,右侧为1,因此可以在排序后预处理出0,和1出现的次数,之后次数就是0,1个数和。
- 考虑到有阈值相同的情况,此时我们要的结果仅应得到第一个和他相同的阈值,可以用二分查找得到第一个相同的元素
AC代码
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define debug(x) cout << "> " << x << endl;
#define endl '\n'
//#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 10 + 1e5, mod = 1e9 + 7;
int n;
PII a[N];
int cnt0[N], cnt1[N];
int binary_s(int i)
{
int x = a[i].first;
int l = 0, r = n + 1;
while (l + 1 != r)
{
int mid = l + r >> 1;
if (a[mid].first < x) l = mid;
else r = mid;
}
return r;
}
void solve()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d%d", &a[i].first, &a[i].second);
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++)
{
if (a[i].second == 1)
cnt1[i] = cnt1[i - 1] + 1, cnt0[i] = cnt0[i - 1];
else cnt0[i] = cnt0[i - 1] + 1, cnt1[i] = cnt1[i - 1];
}
int mx = -inf, res = 0;
for (int i = 1; i <= n; i++)
{
int id = binary_s(i);
int tot = cnt0[id - 1] + (cnt1[n] - cnt1[id - 1]);
if (tot > mx)
{
mx = tot;
res = a[id].first;
}
else if (tot == mx)
res = max(res, a[id].first);
}
printf("%d", res);
}
signed main()
{
solve();
return 0;
}