期末预测之最佳阈值
在一开始使用了双重循环的做法,没有考虑时间复杂度的问题,最终虽然结果正确了,但是提交后显示运行时间超时,看来复杂度为n2并不满足题目的要求。
之后便开始想办法降低复杂度,一开始是想对本来的代码进行改进,但是最终没有成功,不过学会了一个c++中sort函数的新用法,可以定义一个cmp函数来作为sort比较的方法,
bool cmp(pair<int,bool>a,pair<int,bool>b)
{
return a.first < b.first;
}//根据pair中的第一个值进行升序排序
如上,这样就可以在vector数组的元素为pair时,根据first或者second来进行排序了。
之后再网上学习了本题的其他解法,依然是首先根据阈值来进行排序,之后的做法比较聪明,就是建立两个数组,分别存贮对应下标的pair阈值数组的前缀为0的个数和后缀为1的个数,相加即可代表预测正确的总个数,最后再通过下标计算、比较每个阈值的正确个数。
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
bool cmp(pair<int,bool>a,pair<int,bool>b)
{
return a.first < b.first;
}//根据pair中的第一个值进行升序排序
int main(int argc, char** argv) {
int m,k = -1,ma = 0;
cin >> m;
vector<pair<int,bool> > pii(m+1);
pii[0] = pair<int,int>(-1,-1);
vector<int> pre0(m+1,0);
vector<int> rear1(m+1,0);
int te = 0;
bool res = 0;
for(int i = 0;i<m;++i){
cin>>pii[i].first>>pii[i].second;
}
sort(pii.begin()++,pii.end(),cmp);
for(int i = 1;i <= m;++i) //记录前缀0个数
if(pii[i].second == 0)
pre0[i] = pre0[i - 1] + 1;
else
pre0[i] = pre0[i - 1];
for(int i = m;i >= 1;--i) //记录后缀1个数
if(pii[i].second == 1)
rear1[i] = rear1[i + 1] + 1;
else
rear1[i] = rear1[i + 1];
for(int i = 1;i <= m;++i){ //最终处理
if(pii[i].first == pii[i - 1].first)
continue; //如果有阈值相同的情况,那么在相同区间的第一个位置统计了,直接跳过
if(ma <= pre0[i - 1] + rear1[i])//更新k和ma
ma = pre0[i - 1] + rear1[i],k = pii[i].first;
}
cout<<k;
return 0;
}
本部分代码大量cv自此博客:https://blog.csdn.net/qq_45985728/article/details/114903481,感谢大佬的分享。