CCF认证(2)——期末预测之最佳阈值

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,就这一点便于求前缀和!而且后面也不容易出错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值