蓝桥杯-数三角(ac代码时间复杂度分析)

问题描述

小明在二维坐标系中放置了 ( n ) 个点,他想在其中选出一个包含三个点的子集,这三个点能组成三角形。然而这样的方案太多了,他决定只选择那些可以组成等腰三角形的方案。请帮他计算出一共有多少种选法可以组成等腰三角形?

输入格式

输入共 ( n+1 ) 行。

第一行为一个正整数 ( n )。

后面 ( n ) 行,每行两个整数 ( x_i ) 和 ( y_i ) 表示第 ( i ) 个点的坐标。

输出格式

输出共 1 行,一个整数。

样例输入

5
1 1
4 1
1 0
2 1
1 2

样例输出

4

评测用例规模与约定

  • 对于 20% 的数据,保证 ( n <= 200)。
  • 对于 100% 的数据,保证 ( n <= 2000),( 0 <= xi, yi <= 1e9)。

题解:

正常的暴力代码👇 时间复杂度O(n^3) 会超时, 只过了不到一半数据

#include <bits/stdc++.h>
using namespace std;
#define int doubleconst signed N = 1e4;int a[N], b[N];signed main()
{signed n; cin >> n;for (signed i = 0; i < n; i ++) cin >> a[i] >> b[i];int cnt = 0;for (signed i = 0; i < n; i ++)for (signed j = i + 1; j < n;  j ++)for (signed k = j + 1; k < n; k ++){int x1 = sqrt((a[i] - a[j]) * (a[i] - a[j]) + (b[i] - b[j]) * (b[i] - b[j]));int x2 = sqrt((a[j] - a[k]) * (a[j] - a[k]) + (b[j] - b[k]) * (b[j] - b[k]));int x3 = sqrt((a[i] - a[k]) * (a[i] - a[k]) + (b[i] - b[k]) * (b[i] - b[k]));if (x1 + x2 > x3 && x1 + x3 > x2 && x2 + x3 > x1){if (abs(x1 - x2) < 1e-8 && abs(x2 - x3) < 1e-8 && abs(x1 - x3) < 1e-8) continue;  // 等边三角形不算, 也可以不写, 因为题中要求横纵坐标都是整数, 那么不可能构成等边三角形if (abs(x1 - x2) < 1e-8 || abs(x2 - x3) < 1e-8 || abs(x1 - x3) < 1e-8)  // double 类型判断是否相同要用差来判断, double类型的变量在计算机中存储的值会丢失精度, 不能直接用==cnt ++;}}cout << cnt << endl;return 0;
}

ac代码

这题的思路是尽可能优化时间复杂度,

  • 我们枚举每个点, 然后对该点生成一个hash表, 把到该点距离相同的点放到一个数组中, 然后遍历这个hash表中的所有数组,任选数组中的两个点, 判断这三个点是否满足条件

ac代码👇 这个的时间复杂度是在O(n^2) 和 O(n^3)之间的

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define x first
#define y second
typedef pair<int, int> PII;
const double cha = 1e-8;
vector<PII> v;double dist(int x1, int y1, int x2, int y2)
{return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}bool check(PII a, PII b, PII c)
{double x1 = dist(a.x, a.y, b.x, b.y);double x2 = dist(a.x, a.y, c.x, c.y);double x3 = dist(b.x, b.y, c.x, c.y);if (x1 + x2 <= x3 || x1 + x3 <= x2 || x2 + x3 <= x1) return false;  // 不能构成三角形if (abs(x1 - x2) < cha && abs(x1 - x3) < cha && abs(x2 - x3) < cha) return false;  // 是等边三角形。也可以不写, 因为题中要求横纵坐标都是整数, 那么不可能构成等边三角形return true;
}signed main()
{int n; cin >> n; v.resize(n);for (int i = 0; i < n; i ++) cin >> v[i].x >> v[i].y;int cnt = 0;for (int i = 0; i < n; i ++){unordered_map<double, vector<int>> mp;  // 选用i为一个点的前提下, 其他点到i距离相同的点存放到一个 vector中for (int j = 0; j < n; j ++){if (i == j) continue;double dis = dist(v[i].x, v[i].y, v[j].x, v[j].y);  // 计算距离mp[dis].emplace_back(j);  }for (auto it : mp){vector<int> vv;vv = it.second;  // vv 是到i距离相同的点的 集合, 也就是说vv中的元素都是到i的距离相同的点for (int j = 0; j < vv.size(); j ++)for (int k = j + 1; k < vv.size(); k ++){if (check(v[i], v[vv[j]], v[vv[k]])) cnt ++;  // 因为vv里面存的是下标, 所以是 v[vv[j]]}}}cout << cnt << endl;return 0;
}

下面是笔者自己理解的ac代码的时间复杂度的分析

hash时间复杂度分析:

中间的点在执行hash时是最耗时的, 而且图中这种方式的点分布也是让所有点的时间复杂度尽可能多的情况。

下面分别是vector的个数和map个数分析

  • 因为坐标的横纵坐标都只能是整数, 所有一个 map映射的vector中最多有4个数, 也就是说距离到i坐标相同的点最多有4个, 上下左右距离相同 4个, 4个对焦的点距离相同.

  • 而map映射的个数是 中间的点的最外围每增加一圈, map映射的个数加2, 因为每增加一圈 横纵的距离+1, 斜线的距离+根号2, 一共是两种

hash执行总次数 m 和总个数 n 之间的大小关系分析

当点的个数增加到2000的时候, 实际hash执行的次数不到2000 (map的映射个数不到 100,(这里按50个外圈, 50 * 50是2500个点的个数, 比2000个点大), vecotr中最多是4个点, 4 * 4 = 16) 所以hash执行的次数是100 * 16 == 1600, 这还是中间点的情况, 而且是按2500个点算, 其他点的遍历次数更少 ( m < n )

还有就是, 从上面的分析可以看到, 点的个数越小, 遍历hash的总次数有可能反而比 n 次还要多, 但是当点的个数n边大的时候, 遍历hash的总次数会比(n - 1)小很多。------> 比如一共9个点, 3*3, 中间的点正常应该遍历(n - 1) = 8次, 但是用hash的话应该遍历了 2 * (4 * (4 - 1) / 2) = 12次, 2是hash的两个映射 距离为1和距离为根号2, 4是距离为1和根号2的vector中各有4各元素 。(ps:代码中的for ( int j = 0; j < vv.size(); j ++);for (int k = j + 1; k < vv.size(); k ++) 时间复杂度是(n * (n - 1) / 2)

总的时间复杂度

当点的个数比较大的时候, O(n * (n + m)), m < n, 时间复杂度很OK
即使当点的个数n比较小的时候m可能比n大, 但无伤大雅, 因为它不会比n大特别多,而且也说了 n 比较小这个前提, 这个ac代码的时候复杂度可以看成是O(n^2)

觉得写的不错的话, 点个赞吧~

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

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

相关文章

WXML模板语法-事件绑定

一、 1.事件 事件是渲染层到逻辑层的通讯方式&#xff0c;通过事件可以将用户在渲染层产生的行为&#xff0c;反馈到逻辑层进行业务的处理 2.小程序中常用的事件 3.事件对象的属性列表 当事件回调触发的时候&#xff0c;会收到一个事件对象event&#xff0c;其属性为&#x…

在uni-app 插件市场下载 SKU 插件之后,引入项目报错问题

引入&#xff1a; git 提交报错&#xff1a; 原因&#xff1a;项目使用了 eslint 语法检查 解决&#xff1a;禁用 eslint 语法规则 在<script> 标签下面添加 /* eslint-disable */ 重新提交即可

【网络技术】【Kali Linux】Wireshark嗅探(十四)QUIC(快速UDP互联网连接)协议报文捕获及分析

往期 Kali Linux 上的 Wireshark 嗅探实验见博客&#xff1a; 【网络技术】【Kali Linux】Wireshark嗅探&#xff08;一&#xff09;ping 和 ICMP 【网络技术】【Kali Linux】Wireshark嗅探&#xff08;二&#xff09;TCP 协议 【网络技术】【Kali Linux】Wireshark嗅探&…

移动硬盘容量消失无法读取的解决方案

在数字化时代&#xff0c;数据的存储和备份变得尤为重要。移动硬盘作为一种便捷、大容量的存储设备&#xff0c;受到许多人的青睐。然而&#xff0c;有时我们可能会遭遇这样的问题&#xff1a;移动硬盘不显示容量且无法访问。这种情况无疑给我们的数据存储和管理带来了巨大的困…

uniapp移动端骨架屏流程

1.使用微信开发者工具来生成骨架屏&#xff1b;在分窗模式下选择页面信息&#xff0c;下拉选择生成骨架屏&#xff1b;他会基于当前页面生成骨架屏的样式 点击确定&#xff1b; 会自动生成这两个文件&#xff1b;一个是html结构文件&#xff0c;一个是css样式文件。 然后把这两…

黄石首家Pearson VUE国际认证考试中心落户湖北理工学院

Pearson VUE 作为 Pearson 集团的专门从事计算机化考试服务的公司&#xff0c;到目前为止&#xff0c;已在全世界165 个国家授权了 4400 多个考试中心以及超过 230 家 PVUE 自有考试中心&#xff0c;其中在中国的有三百多个授权考点和 4 个自有考试中心。Pearson VUE 以其技术和…

LLaMa系列模型详解(原理介绍、代码解读):LLaMA 3

LLaMA 3 2024年4月18日&#xff0c;Meta 重磅推出了Meta Llama 3&#xff0c;Llama 3是Meta最先进开源大型语言模型的下一代&#xff0c;包括具有80亿和700亿参数的预训练和指令微调的语言模型&#xff0c;能够支持广泛的应用场景。这一代Llama在一系列行业标准基准测试中展示…

java学习四

Random 随机数 数组 静态初始化数组 数组在计算机中的基本原理 数组的访问 什么是遍历 数组的动态初始化 动态初始化数组元素默认值规则 Java内存分配介绍 数组在计算机中的执行原理 使用数组时常见的一个问题 案例求数组元素最大值 public class Test1 {public static void ma…

<工控><PLC>汇川Easy521系列PLC与汇川SV630N伺服进行EtherCat通讯的相关配置及指令编写

前言 本系列是关于PLC相关的博文&#xff0c;包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌&#xff0c;汇川、信捷等国内品牌。 除了PLC为主要内容外&#xff0c;PLC相关元器件如触摸屏…

【Unity3D美术】URP渲染管线学习01

扫盲简介 URP渲染管线是Unity3d提供的一种视觉效果更好的渲染模式&#xff0c;类似的还有Built RP&#xff08;默认最普通的渲染模式&#xff09;\ HDRP(超高清&#xff0c;对设备要求高)&#xff0c;视觉效果好&#xff0c;而且占用资源少&#xff01;成为主流渲染管线模式&a…

基于Docker部署GitLab环境搭建

文件在D:\E\学习文档子目录压缩\专项进阶&#xff0c;如ngnix,webservice,linux,redis等\docker 建议虚拟机内存2G以上 1.下载镜像文件 docker pull beginor/gitlab-ce:11.0.1-ce.0 注意&#xff1a;一定要配置阿里云的加速镜像 创建GitLab 的配置 (etc) 、 日志 (log) 、数…

成功案例(IF=7.4)| 代谢组+16s联合分析助力房颤代谢重构的潜在机制研究

研究背景 心房颤动&#xff08;AF&#xff09;是临床上最常见的持续性心律失常&#xff0c;具有显著的发病率和死亡率。高龄是房颤发病率、患病率和进展最显著的危险因素。与年龄在50-59岁之间的参与者相比&#xff0c;80-89岁之间的参与者患房颤的风险增加了9.33倍。目前尚不…

nss刷题(3)

1、[SWPUCTF 2021 新生赛]include 根据提示传入一个file后显示了关于flag的代码 这是一个文件包含&#xff0c;考虑php伪协议&#xff0c;构造payload&#xff1a; ?filephp://filter/readconvert.base64-encode/resourceflag.php 2、[SWPUCTF 2021 新生赛]Do_you_know_http …

Css 提高 - 获取DOM元素

目录 1、根据选择器来获取DOM元素 2.、根据选择器来获取DOM元素伪数组 3、根据id获取一个元素 4、通过标签类型名获取所有该标签的元素 5、通过类名获取元素 目标&#xff1a;能查找/获取DOM对象 1、根据选择器来获取DOM元素 语法&#xff1a; document.querySelector(css选择…

cocos 写 连连看 小游戏主要逻辑(Ts编写)算法总结

cocos官方文档&#xff1a;节点系统事件 | Cocos Creator 游戏界面展示 一、在cocos编译器随便画个页面 展示页面 二、连连看元素生成 2.1、准备单个方块元素&#xff0c;我这里就是直接使用一张图片&#xff0c;图片大小为100x100&#xff0c;锚点为&#xff08;0&#xff0…

ESP32基础应用之使用手机浏览器作为客户端与ESP32作为服务器进行通信

文章目录 1 准备2 移植2.1 softAP工程移植到simple工程中2.2 移植注意事项 3 验证4 添加HTML4.1 浏览器显示自己编译的html4.2 在使用html发数据给ESP324.3 HTML 内容4.4 更新 html_test.html 1 准备 参考工程 Espressif\frameworks\esp-idf-v5.2.1\examples\wifi\getting_sta…

PMapper:助你在AWS中实现IAM权限快速安全评估

关于PMapper PMapper是一款功能强大的脚本工具&#xff0c;该工具本质上是一个基于Python开发的脚本/代码库&#xff0c;可以帮助广大研究人员识别一个AWS账号或AWS组织中存在安全风险的IAM配置&#xff0c;并对IAM权限执行快速评估。 PMapper可以将目标AWS帐户中的不同IAM用户…

Hive环境搭建

1 安装Hive 下载文件 # wget -P /opt/ https://mirrors.huaweicloud.com/apache/hive/hive-2.3.8/apache-hive-2.3.8-bin.tar.gz 解压缩 # tar -zxvf /opt/apache-hive-2.3.8-bin.tar.gz -C /opt/ 修改hive文件夹名字 # mv /opt/apache-hive-2.3.8-bin /opt/hive 配置环境变量 …

【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型

【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型 前言 今天来写一个简单的ernie-c#的例子&#xff0c;主要参考了百度智能云的例子&#xff0c;然后自己改了改&#xff0c;学习了ERNIE模型的鉴权方式&#xff0c;数据流的格式和简单的数据解析&#xff0c;实…

面试八股之MySQL篇1——慢查询定位篇

&#x1f308;hello&#xff0c;你好鸭&#xff0c;我是Ethan&#xff0c;一名不断学习的码农&#xff0c;很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 &#x1f3c3;人生之义&#xff0c;在于追求&#xff0c;不在成败&#xff0c;勤通…