4.27比賽總結

文章目錄

  • T1
  • T2
    • 法一:倍增求 LCA
    • 法二:Dijkstra 求最短路
    • 法三:dfs 求深度
  • T3
  • T4
  • 總結

T1

一道非常簡單的題,結果我因為一句話沒寫掛了 80pts……

題目中沒寫 a a a 數組要按照 b b b 數組的順序,所以對于最大方案,我們需要從最小的開始,這樣后面的才有可能填上。

所以一開始我們要先對 b b b 數組從小到大排序(我就是少寫了這一行……),然后我們就可以開始算方案數了,怎么算呢?

很簡單,首先對于 a 1 a_1 a1?,它前面沒有任何數,所以它能取的方案書就是 b 1 b_1 b1?,然后思考 a 2 a_2 a2?,它前面已經有一個數被選了(因為從小到大排序后后面的數一定包含了前面的數),所以對于 a 2 a_2 a2? 來講它有 b 2 ? 1 b_2-1 b2??1 種選擇,然后是 a 3 , a 4 … a_3,a_4\dots a3?,a4?,一直到 a n a_n an?,這時我們很容易發現:對于 a i a_i ai? 來講,它有 b i ? i + 1 b_i-i+1 bi??i+1 種選擇,再根據乘法原理可知答案是:

a n s = ∏ i = 1 n b i ? i + 1 ans=\prod_{i=1}^nb_i-i+1 ans=i=1n?bi??i+1

然后直接輸出答案即可。

(老規矩。)

T2

這道題很簡單,這里我提供三種做法。

在此之前,我們首先要確定一件事:如果牛郎與織女之間的距離是一個奇數,那么他們會在橋上,否則會在星球上。接下來就是怎么求距離的問題了。

法一:倍增求 LCA

我們可以通過倍增求 LCA 并記錄下距離,代碼很簡單,時間復雜度: O ( Q log ? 2 ( N ) ) O(Q\log_2(N)) O(Qlog2?(N))

代碼:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q,l,depth[100006],st[100006][26];
vector<int>v[100006];
void LCA(int x,int y)
{if(depth[x]<depth[y]){swap(x,y);}for(int i=20;i>=0;i--){if(depth[st[x][i]]>=depth[y]){x=st[x][i];l+=(1<<i);}}//這里為了節省時間,我直接把后面求 LCA 的過程省略了。//因為后面的跳動都是兩邊同時跳,那么每次加的距離都是偶數,而加偶數并不會改變它的奇偶性。
}
void dfs(int x,int deep,int fa)
{st[x][0]=fa;depth[x]=deep;for(auto i:v[x]){if(i==fa){continue;}dfs(i,deep+1,x);}
}
signed main()
{// freopen("bridge.in","r",stdin);// freopen("bridge.out","w",stdout);cin>>n>>q;for(int x,y,i=1;i<n;i++){cin>>x>>y;v[x].emplace_back(y);v[y].emplace_back(x);}dfs(1,1,0);for(int i=1;i<=20;i++){for(int j=1;j<=n;j++){st[j][i]=st[st[j][i-1]][i-1];}}while(q--){int x,y;l=0;cin>>x>>y;LCA(x,y);if(l&1){cout<<"Y"<<endl;}else{cout<<"N"<<endl;}}return 0;
}

法二:Dijkstra 求最短路

我們可以把它看作一張圖,然后直接跑最短路。

(我沒有代碼,讀者自己寫吧……)

法三:dfs 求深度

我們可以把兩點間距離,看作是兩點間的深度之和,然后判斷奇偶。

代碼(題解的):

#include <bits/stdc++.h>
#include <stdio.h>
using namespace std;
int n, q, a, b;
vector<vector<int>> s(1e5 + 1);
vector<int> d(1e5 + 1, 1e5);
void dfs(int x, int y) {d[x] = y;for (auto p : s[x]) {if (d[p] > y + 1) {dfs(p, y + 1);}}
}
int main() {cin >> n >> q;for (int i = 0; i < n - 1; i++) {cin >> a >> b;s[a].push_back(b);s[b].push_back(a);}dfs(1, 0);for (int i = 0; i < q; i++) {cin >> a >> b;cout << (((d[a] + d[b]) % 2 == 0) ? "N" : "Y") << endl;}
}

三種方法,任你選擇。

T3

一道不是很簡單的題……

我的基礎想法是用 tarjan 縮點然后再做,但是圖不連通,那么跑 tarjan 的時間復雜度就到了 O ( n 2 ) O(n^2) O(n2),所以明顯不行。

然后我又思考過跑 dfs 來找連通塊,結果時間復雜度還是 O ( n 2 ) O(n^2) O(n2)

于是就只有一種方法了:并查集

然后我們就可以標記連通塊了。

當然,我們肯定要用個 vector 保存下來每個連通塊內的點,接下來又該怎么做呢?

我們要代價最小,說白了就是找離 i i i 最近的點 j j j,然后我就有了一個想法:二分!(從時間復雜度上也看得出來是 O ( T × N log ? 2 ( N ) ) O(T\times N\log_2(N)) O(T×Nlog2?(N))

我們可以用 lower_bound 找出第一個大于等于 i i i 的點,那么它的上一個就是最后一個小于 i i i 的點,這兩個點就必然是離 i i i 最近的兩個點,然后記錄下來就行了。

我們要讓 1 1 1 能到 n n n 連通,那么我們就只需要稍微改一下上面的過程:在包含的 1 1 1 這個連通塊里面二分找第 i i i 個點的 lower_bound

因為二分需要單調性,所以我們可以在這之前對每個連通塊里面的點排序一下,但這明顯會 T L E \color{blue}{TLE} TLE,又該怎么優化呢?

很簡單,我們只需要請出排序的“老大哥”——set。我們把 vector 換成 set 就行了。

然后就水靈靈的 A C \color{green}{AC} AC 了!

代碼:

#include<bits/stdc++.h>
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
int t,n,m,num,ans=INF,fa[100006],col[100006],b[100006],cost[2][100006];
set<int>s[100006];
int find(int x)
{if(fa[x]==x){return x;}return fa[x]=find(fa[x]);
}
signed main()
{cin>>t;while(t--){ans=INF;//初始化!!!for(int i=1;i<=num;i++){s[i].clear();}num=0;memset(b,0,sizeof(b));memset(col,0,sizeof(col));cin>>n>>m;for(int i=1;i<=n;i++){fa[i]=i;}for(int i=1,x,y;i<=m;i++){cin>>x>>y;int xb=find(x);int yb=find(y);if(xb!=yb){fa[yb]=xb;}}if(find(1)==find(n)){cout<<0<<endl;continue;}for(int i=1;i<=n;i++){if(!b[find(i)]){b[find(i)]=col[find(i)]=++num;s[num].insert(i);}else{col[find(i)]=b[find(i)];s[col[find(i)]].insert(i);}}memset(cost,INF,sizeof(cost));for(int i=1;i<=n;i++){if(find(i)==find(1)){continue;}auto it=s[col[find(1)]].lower_bound(i);auto it1=it;if(it1==s[col[find(1)]].end()){it1--,it--;}else if(it1==s[col[find(1)]].begin());else{it--;}cost[0][col[find(i)]]=min({cost[0][col[find(i)]],((*it)-i)*((*it)-i),((*it1)-i)*((*it1)-i)});}for(int i=1;i<=n;i++){if(find(i)==find(n)){continue;}auto it=s[col[find(n)]].lower_bound(i);auto it1=it;if(it1==s[col[find(n)]].end()){it1--,it--;}else if(it1==s[col[find(n)]].begin());else{it--;}cost[1][col[find(i)]]=min({cost[1][col[find(i)]],((*it)-i)*((*it)-i),((*it1)-i)*((*it1)-i)});}for(int i=1;i<=n;i++){if(find(i)==find(1)){continue;}else if(find(i)==find(n)){ans=min(ans,cost[0][col[find(n)]]);}else{ans=min(ans,cost[0][col[find(i)]]+cost[1][col[find(i)]]);}}cout<<ans<<endl;}return 0;
}

當然,這份代碼稍微復雜了點,看看題解代碼:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 100010
int n, m, i, j, k;
set<int>s[N];
set<int>::iterator it, jt, kt;
int f[N], p[N], u, v, a, b, ans, t;
int fa(int x) {return f[x]==x ? x : f[x]=fa(f[x]);
}
int pingfang(int x) {return x*x;
}
int len(int x, int y) {int ans=1e18;for(it=s[x].begin(); it!=s[x].end(); ++it) {jt=s[y].lower_bound(*it);if(jt!=s[y].end()) ans=min(ans, pingfang((*jt)-*it));if(jt!=s[y].begin()) ans=min(ans, pingfang((*(--jt))-*it));}return ans;
}
signed main() {scanf("%lld", &t);while(t--) {scanf("%lld%lld", &n, &m);for(i=1; i<=n; ++i) f[i]=i;for(i=1; i<=n; ++i) s[i].clear();for(i=1; i<=m; ++i) scanf("%lld%lld", &u, &v), f[fa(u)]=fa(v);for(i=1; i<=n; ++i) s[fa(i)].insert(i);a=f[1];b=f[n];ans=len(a, b);for(i=1; i<=n; ++i) {if(f[i]==a||f[i]==b||f[i]!=i) continue;ans=min(ans, len(i, a)+len(i, b));}printf("%lld\n", ans);}return 0;
}

真簡略……

T4

我的評價:特別簡單但是很迷惑人……

這題看上去很復雜,實則一點也不復雜。

對于 50pts,我們可以這么思考:如果兩個點之間可以互相運送垃圾,則連上一條邊,那么同一個連通分量中,所有的垃圾都可以匯集到一個點上,所以問題等價于詢問圖中有多少個連通分量。

但是這樣做最壞情況下時間復雜度為 O ( n 2 ) O(n^2) O(n2),所以我們肯定要換種方法。

(由于作者實在不是很會描述(懶),于是貼上了一份題解。)

我們對所有點按照 x x x 坐標排序,如果前面的點中 y y y 的最小值小于當前點,我們則對這兩個點連邊。
同時我們倒序遍歷,如果后面點的 y y y 的最大值大于當前點,我們則對這兩個點連邊。
這樣邊的數量就降為了 O ( n ) O(n) O(n)

(說實話,我也沒太看懂……只是大致有感覺。)

代碼:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,x[100006],y[100006],mny[100006],mxy[100006],a[100006];
bool cmp(int xx,int yy)
{return x[xx]<x[yy]||x[xx]==x[yy]&&y[xx]<y[yy];
}
signed main()
{cin>>n;for(int i=1;i<=n;i++){cin>>x[i]>>y[i];a[i]=i;}sort(a+1,a+n+1,cmp);mny[1]=y[a[1]];for(int i=2;i<=n;i++){mny[i]=min(mny[i-1],y[a[i]]);}mxy[n]=y[a[n]];for(int i=n-1;i>=1;i--){mxy[i]=max(mxy[i+1],y[a[i]]);}int ans=1;for(int i=1;i<n;i++){if(mny[i]>mxy[i+1]){ans++;}}cout<<ans;return 0;
}

總結

  1. T1: 本來應該 A C \color{green}{AC} AC 的,結果掛了 80pts……
  2. T2: 完美 A C \color{green}{AC} AC
  3. T3: 理論上來講可以拿到 50pts,但因為一些奇奇怪怪的計算機底層問題而 W A \color{red}{WA} WA 了……(還有 T L E \color{blue}{TLE} TLE。)
  4. T4: 根本不會,直接輸出了樣例,騙到 8pts。

總分:129pts,滿分 400pts,反正我不滿意。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77794.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77794.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77794.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據一致性巡檢總結:基于分桶采樣的設計與實現

數據一致性巡檢總結&#xff1a;基于分桶采樣的設計與實現 背景 在分布式系統中&#xff0c;緩存&#xff08;如 Redis&#xff09;與數據庫&#xff08;如 MySQL&#xff09;之間的數據一致性問題是一個常見的挑戰。由于緩存的引入&#xff0c;數據在緩存和數據庫之間可能存…

SpringBoot與Druid整合,實現主從數據庫同步

通過引入主從數據庫同步系統&#xff0c;可以顯著提升平臺的性能和穩定性&#xff0c;同時保證數據的一致性和安全性。Druid連接池也提供了強大的監控和安全防護功能&#xff0c;使得整個系統更加健壯和可靠。 我們為什么選擇Druid&#xff1f; 高效的連接管理&#xff1a;Dru…

在Linux系統中安裝MySQL,二進制包版

1、檢查是否已安裝數據庫&#xff08;rpm軟件包管理器&#xff09; rpm -qa | grep mysql rpm -qa | grep mariadb #centOS7自帶mariadb與mysql數據庫沖突2、刪除已有數據庫 rpm -e –nodeps 軟件名稱 3、官網下載MySQL包 4、上傳 # 使用FinalShell或Xshell工具上傳&#…

【含文檔+PPT+源碼】基于SpringBoot電腦DIY裝機教程網站的設計與實現

項目介紹 本課程演示的是一款 基于SpringBoot電腦DIY裝機教程網站的設計與實現&#xff0c;主要針對計算機相關專業的正在做畢設的學生與需要項目實戰練習的 Java 學習者。 1.包含&#xff1a;項目源碼、項目文檔、數據庫腳本、軟件工具等所有資料 2.帶你從零開始部署運行本套…

Spring Boot 緩存機制:從原理到實踐

文章目錄 一、引言二、Spring Boot 緩存機制原理2.1 緩存抽象層2.2 緩存注解2.3 緩存管理器 三、入門使用3.1 引入依賴3.2 配置緩存3.3 啟用緩存3.4 使用緩存注解3.5 實體類 四、踩坑記錄4.1 緩存鍵生成問題4.2 緩存過期與更新問題4.3 事務與緩存的一致性問題 五、心得體會5.1 …

Spark讀取Apollo配置

--conf spark.driver.extraJavaOptions-Dapp.idapollo的app.id -Denvfat -Dapollo.clusterfat -Dfat_metaapollo的meta地址 --conf spark.executor.extraJavaOptions-Dapp.idapollo的app.id -Denvfat -Dapollo.clusterfat -Dfat_metaapollo的meta地址 在spark的提交命令中&…

[逆向工程]如何理解小端序?逆向工程中的字節序陷阱與實戰解析

[逆向工程]如何理解小端序&#xff1f;逆向工程中的字節序陷阱與實戰解析 關鍵詞&#xff1a;逆向工程、小端序、字節序、二進制分析、數據解析 引言&#xff1a;為什么字節序是逆向工程師的必修課&#xff1f; 在逆向工程中&#xff0c;分析二進制數據是最基礎的任務之一。…

項目三 - 任務2:創建筆記本電腦類(一爹多叔)

在本次實戰中&#xff0c;我們通過Java的單根繼承和多接口實現特性&#xff0c;設計了一個筆記本電腦類。首先創建了Computer抽象類&#xff0c;提供計算的抽象方法&#xff0c;模擬電腦的基本功能。接著定義了NetCard和USB兩個接口&#xff0c;分別包含連接網絡和USB設備的抽象…

ElasticSearch深入解析(六):集群核心配置

1.開發模式和生產模式 Elasticsearch默認運行在開發模式下&#xff0c;此模式允許節點在配置存在錯誤時照常啟動&#xff0c;僅將警告信息寫入日志文件。而生產模式則更為嚴格&#xff0c;一旦檢測到配置錯誤&#xff0c;節點將無法啟動&#xff0c;這是一種保障系統穩定性的安…

【Prometheus-MySQL Exporter安裝配置指南,開機自啟】

目錄 1. 創建 MySQL 監控用戶2. 配置 MySQL 認證文件3. 安裝 mysqld_exporter4. 配置 Systemd 服務5. 啟動并驗證服務6. 修改Prometheus配置常見錯誤排查錯誤現象排查步驟 6. 驗證監控數據關鍵注意事項 7. Grafana看板 1. 創建 MySQL 監控用戶 mysql -uroot -p123456 # 登錄M…

redis未授權訪問漏洞學習

一、Redis常見用途 1. Redis介紹 全稱與起源: Redis全稱Remote Dictionary Service(遠程字典服務)&#xff0c;最初由antirez在2009年開發&#xff0c;用于解決網站訪問記錄統計的性能問題。發展歷程: 從最初僅支持列表功能的內存數據庫&#xff0c;經過十余年發展已支持多種…

4.27搭建用戶界面

更新 router下面的index.js添加新的children 先區分一下views文件夾下的不同vue文件&#xff1a; Home.vue是繪制home頁面的所有的表格。 Main.vue是架構頭部和左側目錄的框架的。 研究一下這個routes對象&#xff0c;就可以發現重定向redirect的奧妙所在&#xff0c;我們先把…

【MySQL】(8) 聯合查詢

一、聯合查詢的作用 由于范式的規則&#xff0c;數據分到多個表中&#xff0c;想要查詢完整的信息&#xff0c;就需要聯合查詢多張表。比如查詢學生的學生信息和所在班級的信息&#xff0c;就需要聯合查詢學生表和班級表。 二、聯合查詢過程 案例&#xff1a;查詢學生姓名為孫…

圖漾官網Sample_V1版本C++語言完整參考例子---單相機版本

文章目錄 1.參考例子 主要梳理了圖漾官網Sample_V1版本的例子 1.參考例子 主要增加了從storage區域讀取相機參數的設置&#xff0c;使用圖漾PercipioViewer軟件&#xff0c;如何將相機參數保存到srorage區&#xff0c;可參考鏈接&#xff1a;保存相機參數操作 保存參數設置 注…

關于本地端口啟動問題

如何啟動一個本地端口 1. Node.js (使用Express框架) 使用node.js的方法 注意&#xff1a;下列bash命令最好在管理員權限運行的cmd窗口中進行&#xff0c;否則可能會有權限錯誤 首先&#xff0c;確保您已經安裝了Node.js和npm。然后&#xff0c;創建一個新的Node.js項目并安…

產銷協同的作用是什么?又如何對各部門發揮作用?

目錄 一、產銷協同的對象有哪些&#xff1f; 1. 客戶需求 2. 市場趨勢 3. 供應鏈伙伴 4. 企業戰略目標 二、產銷協同的作用是什么&#xff1f; 1. 提高客戶滿意度 2. 降低企業成本 3. 增強市場競爭力 4. 優化資源配置 三、產銷協同對各部門怎么發揮作用&#xff1f;…

React Router v7 從入門到精通指南

一、設計思想與核心原理 1. 設計哲學 組件即路由&#xff1a;路由以 <Route> 組件形式聲明&#xff0c;與 React 組件樹深度集成聲明式導航&#xff1a;通過 <Link> 和 useNavigate 實現無刷新路由跳轉動態匹配機制&#xff1a;路徑參數、通配符、優先級匹配規則…

Python爬蟲實戰:獲取網yi新聞網財經信息并做數據分析,以供選股做參考

一、引言 在財經領域,股市信息對投資者意義重大。網yi新聞作為知名新聞資訊平臺,其股市板塊蘊含豐富的最新股市熱點信息。然而,依靠傳統人工方式從海量網頁數據中獲取并分析這些信息,效率低下且難以全面覆蓋。因此,利用爬蟲技術自動化抓取相關信息,并結合數據分析和機器…

Spring Boot Actuator - 應用監控與管理

一、 Spring Boot Actuator 概述 Spring Boot Actuator是Spring Boot 提供的生產級監控與管理工具集&#xff0c;用于實時監控和運維管理應用。Actuator 通過HTTP 端點&#xff08;或 JMX 端點&#xff09;暴露應用的健康狀態、性能指標、日志信息、環境配置等關鍵數據&#x…

不同類型插槽的聲明方法和對應的調用方式

在 Vue 3 中&#xff0c;slot 用于讓組件的使用者可以向組件內部插入自定義內容。Vue 3 提供了多種聲明和使用插槽的方式&#xff0c;下面為你詳細介紹不同類型插槽的聲明方法和對應的調用方式。 1. 匿名插槽 聲明方法 在組件模板中直接使用 標簽來定義匿名插槽&#xff0c;它可…