202012-2 期末预测之最佳阈值
暴力思路为枚举每个人的分数,将当前分数作为阈值,统计预测正确的个数,取预测正确个数最大的作为最终的阈值,复杂度为:\(O(n^2)\)。
我们可以先将所有人的分数排个序,这样在枚举第\(i\)个人的分数作为阈值时,\(1 \sim i-1\)的分数都小于\(i\),\(i+1 \sim n\)的分数都大于\(i\)。
这样一来,假设当前阈值为第\(i\)个人的分数,我们只需统计出\(1 \sim i-1\)中标签为\(0\)的个数和\(i \sim n\)中标签为\(1\)的个数,即为预测正确的个数。而这可以通过前缀和和后缀和预处理得到。
注意点
如果两个人分数相同,标签为\(1\)的排列在前面,因为大于等于当前阈值的均算作及格。
const int N=1e5+10;
PII a[N];
int pre[N],suf[N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i].fi>>a[i].se;
sort(a+1,a+n+1,[&](PII a,PII b)
{
if(a.fi != b.fi) return a.fi < b.fi;
return a.se > b.se;
});
for(int i=1;i<=n;i++)
pre[i]=pre[i-1]+(a[i].se==0);
for(int i=n;i>=1;i--)
suf[i]=suf[i+1]+(a[i].se==1);
int score=0,cnt=0;
for(int i=1;i<=n;i++)
if(pre[i-1]+suf[i] >= cnt)
{
cnt=pre[i-1]+suf[i];
score=a[i].fi;
}
cout<<score<<endl;
//system("pause");
return 0;
}