藍橋杯-數三角(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.pswp.cn/bicheng/14766.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/14766.shtml
英文地址,請注明出處:http://en.pswp.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 */ 重新提交即可

Winform 界面管理

winform 打開多個界面時&#xff0c;如果使用 Form.Show 方法&#xff0c;有時候沒注意就把同一個窗體打開多次&#xff0c;這可能會導致數據混亂&#xff0c;如果去判斷窗體是否打開也很麻煩&#xff0c;需要寫一堆的代碼才能實現&#xff0c;為了解決這個問題&#xff0c;我做…

【網絡技術】【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嗅探&…

【Python快速上手(三十一)】- Python MongoDB 詳解

目錄 Python快速上手&#xff08;三十一&#xff09;Python MongoDB 詳解1. 安裝 pymongo2. 連接 MongoDB3. 創建和刪除集合4. CRUD 操作5. 查詢操作6. 索引7. 聚合8. 其他操作9. 連接池和超時10. 實際應用案例 Python快速上手&#xff08;三十一&#xff09; Python MongoDB …

移動硬盤容量消失無法讀取的解決方案

在數字化時代&#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在一系列行業標準基準測試中展示…

2021遼寧省大學生程序設計競賽(正式賽)

比賽經過&#xff1a;寫了七八題&#xff0c;有一個topsort寫錯地方了&#xff0c;本場題目都較為簡單考的知識都比較明顯 補題&#xff1a;有些題目還得多思考其實也不難 目錄 B.阿強的路 C.傳染病統計 D.阿強與網格 E.生活大爆炸 F.Capslock G.字節類型 H.制造游戲幣…

AI模型:開源VS閉源,誰主沉浮?

簡介&#xff1a;評價一個AI模型“好不好”“有沒有發展”&#xff0c;首先就躲不掉“開源”和“閉源”兩條發展路徑。對于這兩條路徑&#xff0c;你更看好哪一種呢&#xff1f; 開源AI模型的優點。 開源AI模型的最大優勢在于其開放性和可訪問性。通過將AI模型的源代碼公開&a…

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相關元器件如觸摸屏…

父子級分類統計分類下數量sql

1 SELECTA.* FROM(SELECTA.project_id,COALESCE ( A.category_id, 0 ) category_id,( -- 其它沒有查詢的分類, 就會是null, 所以會歸為其它CASEWHEN COALESCE ( A.category_name, 其他分類 ) 其他分類 THEN 其他 WHEN COALESCE ( A.category_name, 其他分類 ) 強電系統 THE…

【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選擇…

cmake uninstall like

如果有install_manifest.txt cat install_manifest.txt | sudo xargs rm #cat install_manifest.txt | xargs ls建議make install之前查看有沒有make uninstall目標