CCF认证(2)——期末预测之最佳阈值
问题
本题卡了很久,从暴力求解到排序之后分左右分别求预测成功的次数,都没有拿全。
1.暴力求解就是时间复杂度太高
2.排序求解,当时想到了一个重复出现同一个阈值而结果不同的情况,但一直没想到解决方法,现在想起来有点憨憨
在网上找了题解后,还有点看不懂,先拿去跑了一遍,确实是100。
然后仔细阅读了一下,查了查一些标准库中自带的结构体和方法,感觉挺牛的,确实学到了。
前缀和也是没想到的,通过前缀和能够反复利用已经求出来的sum值,减少时间。
看前面博主的文章有一个set去重,正好就解决了我前面遇到的第二个问题。通过自带的sort对pair排序方式——pair 默认对first升序,当first相同时对second升序。正好实现了,在等于阈值时结果为1才算预测成功的计算。
代码如下,加了一些注释,方便阅读
代码
//期末预测之最佳阈值
#include<iostream>
#include<set>
#include<vector>
#include<algorithm>
#define N 100000
using namespace std;
int main()
{
int sum[N+1] = { 0 };
//这是utility中的模板
pair<int, int> person[N+1];
set<int> myset;
int n = 0;
cin >> n;
//读输入
int temp1, temp2;
for (int i = 1; i <= n; i++) {
cin >> temp1 >> temp2;
person[i] = make_pair(temp1, temp2);
}
//排序
sort(person + 1, person + n + 1);
//求前缀和
for (int i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + person[i].second;
}
int temp3, max = 0, re = 0;
//这边求出每一个标杆值对应的次数
for (int i = 1; i <= n; i++) {
//该元素已经存在【只记录第一次出现,因为,这样相同的值只出现在右边,方便直接使用前缀和】
if (myset.count(person[i].first) == 1) {
//跳过
continue;
}
myset.insert(person[i].first);
//左边的0,右边的1
temp3 = (i - 1) - sum[i - 1];
temp3 += sum[n] - sum[i - 1];
if (temp3 >= max) {
re = person[i].first;
max = temp3;
}
}
cout << re;
return 0;
}
简单说明
在我看了一遍博主的代码后,我自己下手写,然后送去系统,又是错的
仔细看了下,博主是从1~n的数据,而不是0到n-1,就这一点便于求前缀和!而且后面也不容易出错