一、题目
二、思路
(1)以阈值为分界线,左右判断的情况相反,挂科与不挂科的情况也相反。但是值是0和1,考虑到0的相反数还是0,因此将0改为-1。(使得挂科与不挂科人数均能存储,或也可分别存储挂科和不挂科的人数)
(2)从小到大遍历可能的阈值。预测正确人数 = 大于等于阈值的不挂科人数 + 小于阈值的挂科人数。由(1)中将0改为-1对存储的数据进行了一定处理,通过简单的数学可得 ( 大于等于阈值的挂科与不挂科值总和 - 小于阈值的挂科与不挂科值总和 + 总人数 ) / 2 = 预测正确人数 ,同时 大于等于阈值的挂科与不挂科值总和 = 挂科与不挂科值总和 - 小于阈值的挂科与不挂科值总和(参考前缀和,时间复杂度从O(n²)降到O(n))
(3)用map排序、去重、累加。map内部是红黑树实现的,插入、查找和删除操作的平均时间复杂度都是 O(log n) ,因此插入所有元素时间复杂度约为O(nlogn)。
三、代码
#include<bits/stdc++.h>
using namespace std;
struct Stu
{
int y,result;
}stu[100005];
int main()
{
int m,predict=0,tmp=0,all=0,index=0;
cin>>m;
for(int i=1;i<=m;++i)
cin>>stu[i].y>>stu[i].result;
map<int,int> sum;
for(int i=1;i<=m;++i)
{
if(stu[i].result==1)
sum[stu[i].y]+=1;
else
sum[stu[i].y]-=1;
}
for(auto it:sum)
all+=it.second;
for(auto it:sum)
{
if((m+all-2*tmp)/2>=predict)
{
predict=(m+all-2*tmp)/2;
index=it.first;
}
tmp+=it.second;
}
cout<<index<<endl;
return 0;
}
四、提交结果