CSP-202012-2-期末预测之最佳阈值

CSP-202012-2-期末预测之最佳阈值

【70分思路】

  • 本题的难点还是时间复杂度,暴力枚举会导致时间超限。
  • 对于每一个可能的阈值theta,代码都重新计算了整个predict数组,统计预测正确的数目,因为有两个嵌套的循环,使得时间复杂度是O(m^2)
#include <iostream>
using namespace std;
int main() {int m;cin >> m;int* y = new int[m];int* result = new int[m];int* ac_num = new int[m];int ac_num_max = -1, y_max = -1;for (int i = 0; i < m; i++){cin >> y[i] >> result[i];ac_num[i] = 0;}for (int i = 0; i < m; i++){int theta = y[i];int* predict = new int[m];for (int j = 0; j < m; j++){predict[j] = 0;}// 计算predictfor (int j = 0; j < m; j++){if (y[j] >= theta){predict[j] = 1;}}// 统计正确次数for (int j = 0; j < m; j++){if (predict[j] == result[j]){ac_num[i]++;}}// 预测正确的次数最多if (ac_num[i] > ac_num_max){ac_num_max = ac_num[i];y_max = theta;}// 多个阈值均可以达到最高准确率时,选取其中最大的else if (ac_num[i] == ac_num_max){if (theta > y_max){y_max = theta;}}delete[]predict;}cout << y_max;delete[]y;delete[]result;delete[]ac_num;return 0;
}

【100分思路】

【核心思路】:利用排序一次遍历来减少计算量。思路是先将输入的y数组和结果result数组按照y值排序,然后一次性计算不同theta值对应的正确预测数量。这样做可以将时间复杂度降低到O(m log m)(主要是排序的时间复杂度,之后只需线性时间就可以计算所有可能的theta值)
上述代码通过一种巧妙的方法实现了对不同theta(阈值)的处理,仅通过单次遍历数据即可更新基于不同theta值的预测正确数。这种方法的核心在于利用排序后的数据和对预测正确数的连续更新,而不是重新计算每一个可能的theta值对应的预测正确数。以下是这个过程的详细解释:

具体思路

  1. 排序数据: 首先,通过将数据点按y值进行排序,确保在遍历数据时,theta值是逐渐增加的。这意味着,我们只需要考虑在这些y值变化的地方theta可能会导致预测结果的变化,而不是在每个可能的y

  2. 初始化正确预测数: 在开始遍历之前,计算了一个初始的正确预测数,这是基于假设theta小于最小y值(即所有数据点的预测结果都是1)的情况。这相当于设置了一个非常低的初始阈值,使得所有预测都是1,然后计算这个情况下正确预测的数量。

  3. 遍历并更新: 遍历排序后的数据时,每次遇到一个新的y值,都相当于theta发生了变化

    • 如果theta小于当前的y值,当前点的预测结果会是1;
    • 如果theta等于或大于当前的y值,当前点的预测结果则为0(假设预测规则是y >= theta为1,否则为0)。
    • 每当theta变化,都会影响到当前点的预测正确与否。
      • 如果当前点实际结果为1,那么当theta增加到等于当前点的y值时,之前计入的正确预测数需要减1(因为这个点现在被错误地预测为0)
      • 如果当前点的实际结果为0,相反的,当theta增加到等于当前点的y值时,之前未计入的正确预测数需要增加1(因为这个点现在被正确地预测为0)。这一逻辑体现在对currentPredictions的更新上。
  4. 处理相同的y值: 在实际数据中,可能存在多个数据点具有相同的y值。当处理这样的数据点时,只有在所有具有相同y值的数据点都被考虑完毕后,才会更新theta值。这意味着,如果连续几个数据点有相同的y值,我们会在遍历到最后一个具有该y值的数据点后,才考虑theta值的变化对预测正确数的影响。这一点通过跳过重复y值的逻辑实现,从而确保了每个不同的theta值只被考虑一次。

  5. 更新最大准确预测数和theta 在遍历过程中,每次theta变化后,都会评估当前的正确预测数。如果这个数值超过了之前记录的最大准确预测数,或者在达到相同的最大准确预测数时具有更大的theta值,则更新记录的最大准确预测数和对应的theta值。这保证了在所有考虑的theta值中,选择了能够产生最大准确预测数的最大theta值。

#include <iostream>
#include <algorithm>
using namespace std;struct Data {int y;int result;
};// 比较函数,用于sort对Data数组进行排序,基于y值升序排列
bool compareData(const Data& a, const Data& b) {return a.y < b.y;
}int main() {int m;cin >> m; Data* data = new Data[m]; for (int i = 0; i < m; i++) {cin >> data[i].y >> data[i].result;}    sort(data, data + m, compareData); // 对数据点按y值进行升序排序int correctPredictions = 0; // 正确预测的初始数量,假设所有数据点的预测结果都是1for (int i = 0; i < m; i++) {if (data[i].result == 1) {correctPredictions++; // 统计实际结果为1的数量}}int ac_num_max = correctPredictions; // 记录最大准确预测数int y_max = data[0].y; // 记录达到最大准确预测数的y阈值int currentPredictions = correctPredictions; // 当前阈值下的准确预测数for (int i = 0; i < m; i++) {// 如果当前点的实际结果为0,则假设以当前点的y值为阈值时,将使得预测为1的数量增加// 因为实际为0但预测为1的情况会减少if (data[i].result == 0) {currentPredictions++;}else {// 反之,如果实际结果为1,以当前点的y值为阈值会使得这个点预测错误(预测为0),因此准确预测数减少currentPredictions--;}// 跳过重复的y值,避免对相同阈值的重复计算if (i < m - 1 && data[i].y == data[i + 1].y) {continue;}// 更新记录的最大准确预测数及对应的y阈值// 这里的条件是为了确保,当有多个阈值产生相同的最大准确预测数时,选择y值较大的那个if (currentPredictions >= ac_num_max) {ac_num_max = currentPredictions;// 选择下一个不同的y值作为阈值,确保在所有相同的最大准确预测数中选择最大的y值y_max = i < m - 1 ? data[i + 1].y : data[i].y;}}cout << y_max; // 输出达到最大准确预测数的最大y阈值delete[] data; // 释放动态分配的内存return 0;
}

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/677590.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络之一

目录 1.因特网概述 1.1网络、互连网&#xff08;互联网&#xff09;和因特网 1.2.因特网发展的三个阶段 1.3基于ISP的三层架构的因特网 1.4.因特网的组成 2.三种交换方式 2.1电路交换 2.2分组交换 1.因特网概述 1.1网络、互连网&#xff08;互联网&#xff09;和因特网…

2024 新年快乐!

亲爱的朋友们 新年快乐&#xff01;在这个辞旧迎新的时刻&#xff0c;我想先感谢大家一直以来的支持和鼓励。作为一个刚刚踏入博客写作领域的新人&#xff0c;我深感自己的渺小和不足&#xff0c;但更感激你们一直以来的陪伴。 虽然开通 CSDN 的时间很久&#xff0c;但是主要…

Git分支常用指令

目录 1 git branch 2 git branch xx 3 git checkout xx 4 git checkout -b xx 5 git branch -d xx 6 git branch -D xx 7 git merge xx(含快进模式和冲突解决的讲解) 注意git-log: 1 git branch 作用&#xff1a;查看分支 示例&#xff1a; 2 git branch xx 作用&a…

docker进阶 问题1

如何使用Docker的容器调试和故障排查工具&#xff1f; Docker提供了一系列强大的工具来帮助开发者调试和排查容器中的问题。以下是一些关键步骤和工具的使用方法&#xff1a; 查看容器日志&#xff1a;使用docker logs [容器ID或名称]命令可以轻松查看容器的标准输出和错误。…

二分查找的应用

递增序列的查找 补充&#xff1a;return -1的解释 #include <iostream> using namespace std; int s[1000]; int search(int str[],int left,int right,int num){while(left<right){//要不断循环查找-while:既可判断&#xff0c;又可循环int mid(leftright)/2;if(num…

数据结构——5.5 树与二叉树的应用

5.5 树与二叉树的应用 概念 结点的权&#xff1a;大小可以表示结点的重要性 结点的带权路径长度&#xff1a;从树的根到该结&#xff0c;的路径长度&#xff08;经过的边数&#xff09;与该结点权的乘积 树的带权路径长度&#xff1a;树中所有叶结点的带权路径长度之和(WPL) …

与AI对话:编写高效Prompt的指南

与AI对话&#xff1a;编写高效Prompt的指南 一、明确目标 引导AI提供特定格式或内容答案的策略一、明确需求二、使用示例三、设置参数四、分步询问五、使用关键词 利用关键词引导AI重点关注核心内容的技巧一、确定关键概念二、使用专业术语三、强调重要性四、避免相关术语的混淆…

蜂鸣器播放提示音音乐(天空之城)

目录 蜂鸣器播放提示音 蜂鸣器播放音乐&#xff08;天空之城&#xff09; 准备工作 主程序 中断函数 上一节讲了蜂鸣器驱动原理和乐理基础知识&#xff0c;这一节开始代码演示&#xff01; 蜂鸣器播放提示音 先创建工程&#xff1a;蜂鸣器播放提示音 把我们之前模块化的…

python 爬虫篇(3)---->Beautiful Soup 网页解析库的使用(包含实例代码)

Beautiful Soup 网页解析库的使用 文章目录 Beautiful Soup 网页解析库的使用前言一、安装Beautiful Soup 和 lxml二、Beautiful Soup基本使用方法标签选择器1 .string --获取文本内容2 .name --获取标签本身名称3 .attrs[] --通过属性拿属性的值标准选择器find_all( name , at…

Springboot使用kafka的两种方式

在Spring Boot中使用Apache Kafka主要有两种方式&#xff1a;使用Spring Kafka项目和使用Spring Boot的spring-boot-starter-kafka。以下是这两种方式的简要概述&#xff1a; 使用Spring Kafka项目 Spring Kafka是Spring官方提供的一个用于Apache Kafka的集成库。虽然它不是一…

Sentinel 源码分析

Sentinel源码分析 项目源码 1.Sentinel的基本概念 Sentinel实现限流、隔离、降级、熔断等功能&#xff0c;本质要做的就是两件事情&#xff1a; 统计数据&#xff1a;统计某个资源的访问数据&#xff08;QPS、RT等信息&#xff09;规则判断&#xff1a;判断限流规则、隔离规…

20240210使用剪映识别字幕的时候的GPU占比RX580-RTX4090

20240210使用剪映识别字幕的时候的GPU占比RX580-RTX4090 2024/2/10 17:54 【使用剪映识别不同的封装格式&#xff0c;不同的音视频编码&#xff0c;对GPU的占用率可能会有比较大的不同&#xff01;】 很容易发现在在WIN10下使用剪映的时候&#xff0c;X99RX550组合。 GPU部分&…

【Spring】Bean 的生命周期

一、Bean 的生命周期 Spring 其实就是一个管理 Bean 对象的工厂&#xff0c;它负责对象的创建&#xff0c;对象的销毁等 所谓的生命周期就是&#xff1a;对象从创建开始到最终销毁的整个过程 什么时候创建 Bean 对象&#xff1f;创建 Bean 对象的前后会调用什么方法&#xf…

os模块

os 模块是 Python 中用于与操作系统进行交互的标准库之一。它提供了许多函数来执行文件和目录操作&#xff0c;管理进程以及与操作系统交互的其他功能。 下面是一些 os 模块中常用的函数和功能&#xff1a; 文件和目录操作&#xff1a; os.getcwd(): 返回当前工作目录的路径。…

【Go】三、Go并发编程

并发编程 我们主流的并发编程思路一般有&#xff1a;多进程、多线程 但这两种方式都需要操作系统介入&#xff0c;进入内核态&#xff0c;是十分大的时间开销 由此而来&#xff0c;一个解决该需求的技术出现了&#xff1a;用户级线程&#xff0c;也叫做 绿程、轻量级线程、协…

大厂的供应链域数据中台设计

关注我&#xff0c;紧跟本系列专栏文章&#xff0c;咱们下篇再续&#xff01; 作者简介&#xff1a;魔都技术专家兼架构&#xff0c;多家大厂后端一线研发经验&#xff0c;各大技术社区头部专家博主&#xff0c;编程严选网创始人。具有丰富的引领团队经验&#xff0c;深厚业务架…

庆除夕,比特币两日大涨10%

号外&#xff1a;教链内参2024年1月合订本 今日除夕。昨日今日两天&#xff0c;比特币从43k发力上攻&#xff0c;一度涨超10%至47.7k&#xff0c;以独特的方式给全世界的bitcoiners送去了新春的祝福。 一个新鲜的知识&#xff1a;2023年12月22日&#xff0c;第78届联合国大会协…

JVM 执行引擎

概念 执行class文件中的指令&#xff0c;由解释器编译器组成 补充——Java为什么是半编译半解释型语言 因为Java即有编译器也有解释器&#xff0c;可以用其中一种来运行。 程序执行步骤 解释器与编译器区别 编译器 概念 JIT&#xff08;Just In Time Compiler&#xff09;…

vue中使用moment 设置倒计时的方法

vue中使用moment 设置倒计时的方法 日常开发中时常需要使用倒计时的方法 现在进行封装一下 //第一步 引入moment import moment from moment;let nowTime:any ref()//当前时间 let diffTime:any ref()//当前时间和指定时间的差值 let countdown:any ref(0)//倒计时 // 设置…

深入探索Java IO:从基础到高级操作全览

深入探索Java IO&#xff1a;从基础到高级操作全览 Java IO一、概览二、磁盘操作三、字节操作实现文件复制装饰者模式 四、字符操作编码与解码String 的编码方式Reader 与 Writer实现逐行输出文本文件的内容 五、对象操作序列化Serializabletransient 六、网络操作InetAddressU…