一、问题链接
二、思路
map容器
由于数据规模达到了
1
0
5
10^5
105,因此,若采用两层遍历(即,用每一个阀值遍历每一个同学,来判断该阀值是否正确预测)则会超时,只能得到70分。
定义容器为map<long long, array<long long, 2>>
,键为安全指数
y
i
y_i
yi,值为一个大小为2的数组,第一个元素值[0]值为result==0
的学生的个数,第二个元素[1]为result==1
的学生的个数。
由于map容器会将键去重且递增排序,因此,遍历map容器。设当前键为
y
i
y_i
yi(则当前键之前所有键的大小小于该键);p0
记录当前键之前,所有键对应的result==0
的个数和(这一部分全部预测成功),p1
记录当前键之前,所有键对应的result==1
的个数和(这一部分全部预测失败)。
由于当 y==
θ
\theta
θ时且result==1
时预测正确,因此记录所有result==0
的同学的个数为zero
,学生总数为m,m-zero-p1
为当前键(即当前阈值)对于result==1
的同学预测成功的个数。因此当前阈值预测成功的总数为p0 + m - zero - p1
最后记录预测成功次数最多的阈值,若预测成功次数相同,取值最大的阈值。由于map键即为阈值,且从小到大排序,若预测成功次数相同,且均为最大,则取后一个阈值(即map的键)。
三、参考代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
map<ll, array<ll, 2>> r;//安全指数y, [0]挂科人数,[1]未挂科人数
ll m, yi, res, zero=0;
cin >> m;
for (ll i = 0; i < m; ++i) {
cin >> yi >> res;
if(res==0) zero++;//记录result=0的个数
r[yi][res]++;
}
ll p0 = 0, p1 = 0, ans = 0, count = 0;
for (auto& i : r) {
ll temp = p0 + m - zero - p1 ;//当前阀值预测正确次数
if (temp >= count) {//如果相等保存大的
count = temp;
ans = i.first;
}
p0 += i.second[0];//未挂科人数,全部预测正确
p1 += i.second[1];//挂科人数,预测成功m - zero - p1
}
cout<<ans;
return 0;
}