码一下做题记录而已,能跑但不优雅,别误人子弟了QAQ。
题目一堆的数学公式,还是截图方便点,别骂了别骂了。
题目
思路
按照
s
c
o
r
e
score
score排序后计算
[
0
,
i
)
[0,i)
[0,i) 有多少个
0
0
0(类似于前缀和一样),记为preZero
。然后按照一样的方法计算
[
i
,
n
)
[i,n)
[i,n) 有多少个
1
1
1,记为postOne
,因此预测到的正确值的个数为 preZero + postOne
。
一个小坑:对于
s
c
o
r
e
i
=
=
s
c
o
r
e
i
−
1
score_i==score_{i-1}
scorei==scorei−1的情况,要直接continue
,不然同样分数有的人过了有的人挂科会导致同样分数算出来的预测值不一样
时间复杂度: O ( n lg n ) O(n\lg n) O(nlgn),因为要排序,然后遍历一次。
#include <bits/stdc++.h>
using namespace std;
struct DataType{
int y;
int result;
bool operator<(const DataType& b){
return y<b.y || (y==b.y && result<b.result);
}
};
int main(){
const int MAXN = 1e5+10;
int n;
int presum[MAXN];
int prezero[MAXN];
DataType data[MAXN];
int allsum = 0;
int optTheta; // 最佳theta
int optCorrect = 0; // 最佳预测值
cin>>n;
for(int i=0;i<n;++i){
cin>>data[i].y>>data[i].result;
}
sort(data, data+n);
presum[0] = data[0].result;
prezero[0] = 0;
for(int i=1;i<n;++i){ // 计算前缀和
presum[i] = data[i].result + presum[i-1];
prezero[i] = prezero[i-1] + 1 - data[i-1].result;
}
allsum = presum[n-1];
for(int i=0;i<n;++i){
if(i>0 && data[i].y == data[i-1].y){
continue;
}
int curCorrect = prezero[i] // 小于的时候是0的个数
+ (allsum - presum[i]) // 大于的时候是1的个数
+ (data[i].result == 1); // 猜对自己
if(curCorrect >= optCorrect){
optCorrect = curCorrect;
optTheta = data[i].y;
}
}
cout<<optTheta;
return 0;
}